Reproducing Tingley & Buzsáki (2018) from dandiset 000213¶

Paper. Tingley D, Buzsáki G (2018). Transformation of a spatial map across the hippocampal-lateral septal circuit. Neuron 98, 1229-1242. doi:10.1016/j.neuron.2018.04.028. This attempt used the full text of the NIH author manuscript in PubMed Central (PMC6605060): Results, figure legends and STAR Methods. The supplementary figures were not read.

Dandiset. DANDI:000213, version 0.250624.0438. The paper cites no version (its data statement says the data were being prepared for CRCNS). There are two published versions, 0.220127.1738 and 0.250624.0438; they hold the same 67 files with the same asset identifiers and sizes (checked below) and differ only in dandiset-level metadata, so the most recent is pinned.

What the dandiset holds. 67 sessions from the five rats (DT2, DT5, DT7, DT8, DT9): sorted units labelled by region (ls, hpc, ca3 and a few others), LFP at 1250 Hz, head position, and trials. The paper's processed files (linearized behaviour, trial conditions, the CA1 channel of each session) are not in it; they are rebuilt here as described in lshpc.py.

Code read. The paper's figure scripts, https://github.com/DavidTingley/papers (LS_phasecoding, commit 9f4cd48a44f211956954558b66d776ccbb74d693); buzcode, https://github.com/buzsakilab/buzcode (commit e615663b2b100782d1f378580f6d7aaa35c12937); and the per-cell decoder in https://github.com/DavidTingley/scratch (commit 2f804532290774f52a442bf0f3ec23dd5398d58d). The functions that bin phases (bz_phaseMap2Bins), compute information (olypherInfo) and detect assemblies are not public.

Claims. The claims file is claims/000213/10.1016-j.neuron.2018.04.028.yaml.

Claim Tested here
ls-neuron-count: 1,647 LS neurons, 62 sessions Tested
hpc-unit-count: 2,297 CA1 and 654 CA3 units Tested
ls-active-neurons: 840 LS neurons fire at least 1.5 spikes per trial Tested
fig2-ls-phase-vs-shuffle: 89% of LS neurons code position in phase Tested
fig2-ls-phase-beats-rate: phase beats rate in 786/840 neurons, 3,046/4,393 conditions, 62/62 sessions Tested
fig2e-ls-phase-lower-mse: phase MSE below rate MSE across LS conditions and sessions Tested
fig2fg-mse-difference: mean phase minus rate MSE, LS and hippocampus Tested
fig1i-hpc-rate-phase-equivalent: rate and phase decoding equivalent for place fields Tested
ls-few-place-fields: 5.3% of LS and 31.7% of hippocampal rate maps have place fields Tested
hpc-place-field-properties: 711 of 1,425 neurons with fields, 8.5 Hz, 38 bins Tested
ls-place-fields-unstable: LS fields less stable (41.5 against 10) Tested
fig1e-phase-info-smaller-scale: peak information at 15 (phase) and 29 (rate) bins Tested
fig1g-phase-more-info-fine-scale: phase more informative below 6 cm, rate above 10 cm Tested
fig4d-depth-gradient: phase coding grows with LS depth Tested
fig4e-onset-depth: onset phase correlates with depth Tested
fig6c-ca3-coherence-increases: LS-CA3 theta coherence rises along the run Tested
fig6d-cfc-stronger-ca3: theta-gamma coupling rises, stronger for CA3 Tested
figs7-ensemble-ls-phase-best: LS ensemble phases beat hippocampal ensembles Tested
fig5-assemblies: 18.5% of pairs form gamma assemblies Tested on a random sample of 1% of the pairs
ls-information-lower: 0.4 against 1.7 bits/cm Tested
fig5g-assembly-neurons-stronger-phase Blocked: not runnable (needs the assemblies of every pair)
fig6e-assembly-position Blocked: not runnable (needs the assemblies of every pair)
speed-independent: 2.8% of conditions speed-related Blocked: methods underspecified
figs6-reference-frame: maze rotation Blocked: metadata insufficient
fig7-dynamic-weighting-model: spiking model Blocked: other (a simulation)

Revision after the first verification round. Place fields now use the Gaussian rate map that the paper's code passes to bz_getPlaceFields1D (SD 4 bins), where the first version used the 5-bin box map; Figure 6 groups sessions by their unit labels, as its criterion states, and leaves out sessions without hippocampal units; the ensemble tests are one-sided; the theta reference of each session is described and the phase claims are repeated on sessions with a clear theta rhythm; fig5-assemblies is tested on a sample of pairs and ls-information-lower is tested, with criteria added to the claims file in this revision.

Second revision. The sentences the second verifier found unsupported are corrected, and three variants are added: place fields without the rule dropping peaks whose SD across trials exceeds their mean, the onset-phase test on sessions with one theta reference label per rat, and the peer prediction with the LS unit's spatial tuning as a covariate. No outcome changed.

The whole notebook streams the data and takes about twelve to fifteen minutes on four processes, most of it the per-cell decoding and the peer prediction.

In [1]:
import os
os.environ.setdefault("OMP_NUM_THREADS", "1")
os.environ.setdefault("OPENBLAS_NUM_THREADS", "1")
import time
import warnings

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

import lshpc

warnings.filterwarnings("ignore", category=RuntimeWarning)
pd.set_option("display.width", 220)
pd.set_option("display.max_columns", 40)
pd.set_option("display.max_rows", 200)

started = time.time()
results = lshpc.run_all(workers=4)
print(f"streamed and analysed {len(results)} files of dandiset {lshpc.DANDISET_ID} "
      f"version {lshpc.DANDISET_VERSION} in {time.time() - started:.0f} s")
errors = [(r["summary"]["path"], r["error"]) for r in results if "error" in r]
print("files that failed:", errors if errors else "none")

S = pd.DataFrame([r["summary"] for r in results])
S["session"] = S.index
S["name"] = S.session_id.str.slice(0, 32)
C = pd.DataFrame([dict(c, session=i, subject=results[i]["summary"]["subject"])
                  for i, r in enumerate(results) for c in r.get("cells", [])])
C["neuron"] = list(zip(C.session, C.unit))
A = C[C.active].copy()                 # included cell and condition pairs
LS = A[A.region == "ls"]
HP = A[A.region == "hpc"]
LSd = LS[LS.mse_phase.notna()]          # decoded (session has a theta channel)
HPd = HP[HP.mse_phase.notna()]
streamed and analysed 67 files of dandiset 000213 version 0.250624.0438 in 864 s
files that failed: none

Data check¶

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

In [2]:
from dandi.dandiapi import DandiAPIClient

with DandiAPIClient() as client:
    ds = client.get_dandiset(lshpc.DANDISET_ID, lshpc.DANDISET_VERSION)
    meta = ds.get_raw_metadata()
    versions = [v.identifier for v in client.get_dandiset(lshpc.DANDISET_ID).get_versions()]
    listing = {}
    for v in versions:
        if v == "draft":
            continue
        listing[v] = {a.path: (a.identifier, a.size) for a in client.get_dandiset(lshpc.DANDISET_ID, v).get_assets()}
summary = meta["assetsSummary"]
print("Published versions:", [v for v in versions if v != "draft"])
pub = sorted(listing)
same = all(listing[pub[0]] == listing[v] for v in pub[1:])
print(f"Assets identical (path, asset id, size) across published versions: {same}; files: {len(listing[pub[0]])}")
print("Paper named by the dandiset:", [r.get("identifier") for r in meta.get("relatedResource", [])])
print("assetsSummary: subjects", summary.get("numberOfSubjects"), "| species", [s["name"] for s in summary.get("species", [])],
      "| variables", summary.get("variableMeasured"))
print("Subjects in the files:", sorted(S.subject.unique()), "| files per subject:", S.subject.value_counts().sort_index().to_dict())
Published versions: ['0.220127.1738', '0.250624.0438']
Assets identical (path, asset id, size) across published versions: True; files: 67
Paper named by the dandiset: ['https://doi.org/10.1016/j.neuron.2018.04.028']
assetsSummary: subjects 5 | species ['Rattus norvegicus - Norway rat'] | variables ['Position', 'CompassDirection', 'ElectricalSeries', 'LFP', 'Units', 'SpatialSeries']
Subjects in the files: ['DT2', 'DT5', 'DT7', 'DT8', 'DT9'] | files per subject: {'DT2': 11, 'DT5': 16, 'DT7': 9, 'DT8': 17, 'DT9': 14}

The two published versions (2022 and 2025) hold the same 67 files with the same asset identifiers and sizes; they differ only in dandiset-level metadata (contributor identifiers and affiliations, the citation). The newest is pinned. The archive's summary of five rats of one species matches the files. The paper's Methods state five rats, 3 male and 2 female; the files give no sex, so that cannot be checked.

In [3]:
units = (pd.DataFrame([dict(subject=s, location=l, n=n) for s, d in zip(S.subject, S.unit_locations) for l, n in d.items()])
         .pivot_table(index="subject", columns="location", values="n", aggfunc="sum", fill_value=0))
units.loc["all"] = units.sum()
print("Units by region label and subject:")
print(units.to_string())
sess = pd.DataFrame([dict(subject=s, location=l) for s, d in zip(S.subject, S.unit_locations) for l in d])
print("\nSessions holding units of each label:", sess.location.value_counts().to_dict())
print("Files without units:", S[S.n_units == 0].session_id.tolist())
print("Units with spike times not in increasing order:", int(S.units_unsorted.sum()),
      "in", S[S.units_unsorted > 0].session_id.tolist())
print("Units with spikes after the end of the LFP:", int(S.spikes_after_lfp_end.sum()))
print("\nElectrode labels per subject:")
for subj, g in S.groupby("subject"):
    labs = {}
    for d in g.electrode_locations:
        for k, v in d.items():
            labs[k] = labs.get(k, 0) + 1
    print(f"  {subj}: files with each label {labs}")
key = S[["n_spikes_total", "n_units"]].astype(str).agg("|".join, axis=1) + "|" + S.lfp_shape.astype(str)
print("\nFiles sharing total spikes, units and LFP shape:", S[key.duplicated(keep=False)].session_id.tolist())
print("Files sharing identical trial start times:", S[S.trial_starts_rounded.duplicated(keep=False)].session_id.tolist())
depth_rows = S[["subject", "session_id", "ls_depth", "hpc_depth", "has_hpc_units", "has_ca3_units"]]
print("\nDepths in the session names (um), first and second, with the hippocampal labels of the units:")
print(depth_rows.to_string(index=False))
Units by region label and subject:
location  acg  ca3  cc   hpc    ls  ms  ppc  sFi  unlabelled
subject                                                     
DT2         0    0   0  1035   375   0   28    0           0
DT5         0  279   0   329   480   0    0    0           0
DT7        31    0   6   446    60  25    0   54          43
DT8         0    0   0     0   296   0   32    0           0
DT9         0  345   0   783   485   0    0    0           0
all        31  624   6  2593  1696  25   60   54          43

Sessions holding units of each label: {'ls': 62, 'hpc': 36, 'ca3': 11, 'ppc': 2, 'acg': 2, 'cc': 2, 'ms': 2, 'unlabelled': 1, 'sFi': 1}
Files without units: ['20170324_576um_144um_170324_123932']
Units with spike times not in increasing order: 11 in ['DT2_rPPC_rCCG_3324um_1144um_20160219_160219_130435', 'DT2_rPPC_rCCG_3396um_1180um_20160220_160220_141839', '20161018_1552um_2304um_merge', '20161026_1944um_2232um_merge', '20170321_216um_0um_170321_120259', '20170201_72um_432um_merge']
Units with spikes after the end of the LFP: 0

Electrode labels per subject:
  DT2: files with each label {np.str_('unknown'): 11}
  DT5: files with each label {np.str_('hpc'): 10, np.str_('ls'): 16, np.str_('ca3'): 6}
  DT7: files with each label {np.str_('acg'): 6, np.str_('cc'): 2, np.str_('hpc'): 9, np.str_('ls'): 9, np.str_('ms'): 6, np.str_('sFi'): 1}
  DT8: files with each label {np.str_('hpc'): 17, np.str_('ls'): 17}
  DT9: files with each label {np.str_('hpc'): 7, np.str_('ls'): 12, np.str_('unknown'): 2, np.str_('ca3'): 5}

Files sharing total spikes, units and LFP shape: []
Files sharing identical trial start times: []

Depths in the session names (um), first and second, with the hippocampal labels of the units:
subject                                         session_id  ls_depth  hpc_depth  has_hpc_units  has_ca3_units
    DT2 DT2_rPPC_rCCG_3324um_1000um_20160217_160217_103121      3324       1000          False          False
    DT2 DT2_rPPC_rCCG_3324um_1144um_20160219_160219_130435      3324       1144           True          False
    DT2 DT2_rPPC_rCCG_3396um_1180um_20160220_160220_141839      3396       1180           True          False
    DT2 DT2_rPPC_rCCG_3396um_1180um_20160221_160221_135947      3396       1180           True          False
    DT2 DT2_rPPC_rCCG_3468um_1216um_20160222_160222_120902      3468       1216           True          False
    DT2 DT2_rPPC_rCCG_3468um_1216um_20160223_160223_121321      3468       1216           True          False
    DT2 DT2_rPPC_rCCG_3468um_1216um_20160225_160225_130701      3468       1216           True          False
    DT2 DT2_rPPC_rCCG_3468um_1252um_20160226_160226_124132      3468       1252           True          False
    DT2 DT2_rPPC_rCCG_3540um_1288um_20160227_160227_121226      3540       1288           True          False
    DT2 DT2_rPPC_rCCG_3540um_1288um_20160228_160228_135001      3540       1288           True          False
    DT2 DT2_rPPC_rCCG_3612um_1360um_20160304_160304_150220      3612       1360           True          False
    DT5                        20161011_972um_1224um_merge       972       1224           True          False
    DT5                       20161014_1296um_1476um_merge      1296       1476           True          False
    DT5                       20161015_1368um_1476um_merge      1368       1476           True          False
    DT5                       20161016_1368um_1476um_merge      1368       1476           True          False
    DT5                       20161018_1552um_2304um_merge      1552       2304           True           True
    DT5               20161019_1624um_2340um_161019_095311      1624       2340           True           True
    DT5               20161020_1768um_2376um_161020_102642      1768       2376           True          False
    DT5                       20161021_1840um_2412um_merge      1840       2412           True           True
    DT5               20161023_1872um_2448um_161023_123504      1872       2448           True          False
    DT5                       20161025_1944um_2232um_merge      1944       2232           True          False
    DT5                       20161026_1944um_2232um_merge      1944       2232           True          False
    DT5               20161027_1944um_2232um_161027_194125      1944       2232           True          False
    DT5               20161030_2052um_2232um_161030_111142      2052       2232           True          False
    DT5               20161031_2088um_2232um_161031_104001      2088       2232           True           True
    DT5                       20161101_2088um_2232um_merge      2088       2232           True           True
    DT5                       20161104_2124um_2232um_merge      2124       2232           True           True
    DT7                   20170315_288um_0um_170315_191240       288          0           True          False
    DT7                           20170317_288um_0um_merge       288          0          False          False
    DT7                   20170318_288um_0um_170318_115923       288          0           True          False
    DT7                           20170320_432um_0um_merge       432          0           True          False
    DT7                   20170321_216um_0um_170321_120259       216          0           True          False
    DT7                 20170324_576um_144um_170324_123932       576        144          False          False
    DT7                 20170325_576um_360um_170325_125511       576        360           True          False
    DT7                         20170401_864um_936um_merge       864        936           True          False
    DT7               20170412_1440um_1170um_170412_103153      1440       1170           True          False
    DT8                             20170125_0um_0um_merge         0          0          False          False
    DT8                            20170128_0um_72um_merge         0         72          False          False
    DT8                          20170201_72um_432um_merge        72        432          False          False
    DT8                  20170202_72um_576um_170202_092033        72        576          False          False
    DT8                         20170206_72um_1872um_merge        72       1872          False          False
    DT8                        20170207_144um_1944um_merge       144       1944          False          False
    DT8                        20170211_144um_1944um_merge       144       1944          False          False
    DT8                20170214_216um_1944um_170214_102804       216       1944          False          False
    DT8                20170215_216um_1944um_170215_140739       216       1944          False          False
    DT8                        20170216_216um_1944um_merge       216       1944          False          False
    DT8                        20170217_216um_1944um_merge       216       1944          False          False
    DT8                20170218_216um_1944um_170218_114724       216       1944          False          False
    DT8                20170221_324um_1944um_170221_101929       324       1944          False          False
    DT8                20170224_324um_2088um_170224_101710       324       2088          False          False
    DT8                20170305_468um_2088um_170305_135233       468       2088          False          False
    DT8                20170306_468um_2088um_170306_113628       468       2088          False          False
    DT8                        20170308_612um_2088um_merge       612       2088          False          False
    DT9                             20170429_0um_0um_merge         0          0           True          False
    DT9                             20170430_0um_0um_merge         0          0           True          False
    DT9                   20170501_216um_0um_170501_112210       216          0           True          False
    DT9                           20170502_288um_0um_merge       288          0           True          False
    DT9                           20170504_396um_0um_merge       396          0           True          False
    DT9                           20170505_396um_0um_merge       396          0           True          False
    DT9                  20170506_468um_36um_170506_111835       468         36           True          False
    DT9                          20170507_468um_36um_merge       468         36           True          False
    DT9                  20170509_468um_36um_170509_103451       468         36           True          False
    DT9                         20170518_828um_864um_merge       828        864           True           True
    DT9                         20170519_864um_900um_merge       864        900           True           True
    DT9                 20170521_900um_936um_170521_125602       900        936           True           True
    DT9                 20170522_900um_936um_170522_151132       900        936           True           True
    DT9                 20170525_900um_936um_170525_150124       900        936           True           True

Units carry a region label: ls (lateral septum), hpc, ca3, and a few cortical or other labels (acg, cc, ms, ppc, sFi). One file (DT7, 20170317) has units without any label and is left out of every count by region; one (DT7, 20170324) has no units. No two files share their spike totals, unit counts and LFP length, or their trial times, so no recording was deposited twice. Several sessions were recorded at the same depths on consecutive days (for example five DT8 sessions at 216 and 1944 um); each session's units are treated as separate units, as the paper's counts do, and no claim assumes the same unit across sessions.

The electrode labels of sub-DT2 are all unknown; its hippocampal and LS channels are taken from the electrode groups of its labelled units. The session names hold two depths that no metadata describes. In DT9 the units are labelled ca3 exactly in the sessions whose second depth is 828 um or more, which fits the second depth being the hippocampal probe's; the first depth is taken as the LS probe's. This is an assumption, used only by the depth claims. It is not settled by the other rats: in DT5 the files labelled hpc and ca3 alternate at second depths of 2232 to 2448 um, and the DT8 depths (0 to 612 and 0 to 2088 um) do not say which probe is which.

In [4]:
pos = S[["subject", "name", "task", "position_unit_stated", "position_extent_stated_units", "position_unit_used",
         "position_dt_median", "position_dt", "position_nonincreasing_steps", "position_z_equals_y",
         "position_nan_fraction", "path_length_median"]].copy()
pos["extent_1_99"] = pos.position_extent_stated_units.round(2)
print(pos.drop(columns="position_extent_stated_units").round(4).to_string(index=False))
odd = S[(S.position_unit_stated != "pixels") & (((S.position_unit_stated == "mm") & (S.position_extent_stated_units < 10)) |
                                               ((S.position_unit_stated == "m") & (S.position_extent_stated_units > 10)))]
print(f"\nFiles whose stated position unit disagrees with the values: {len(odd)}:", odd.name.tolist())
print("Files whose third position column equals the second:", int(S.position_z_equals_y.sum()), "of", len(S))
print("Files with repeated or decreasing position timestamps:", S[S.position_nonincreasing_steps > 0].name.tolist())
subject                             name                     task position_unit_stated position_unit_used  position_dt_median  position_dt  position_nonincreasing_steps  position_z_equals_y  position_nan_fraction  path_length_median  extent_1_99
    DT2 DT2_rPPC_rCCG_3324um_1000um_2016   wheel_alternation_task               pixels             pixels              0.0333       0.0333                             0                 True                 0.9395           1013.4146       399.29
    DT2 DT2_rPPC_rCCG_3324um_1144um_2016   wheel_alternation_task               pixels             pixels              0.0333       0.0333                             0                 True                 0.9027            990.4751       390.51
    DT2 DT2_rPPC_rCCG_3396um_1180um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        284650                 True                 0.8663           1041.9535       411.93
    DT2 DT2_rPPC_rCCG_3396um_1180um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        503067                 True                 0.8905           1063.7525       397.92
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        335021                 True                 0.8771           1037.1292       404.21
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        159069                 True                 0.3060           1037.3105       351.77
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        387416                 True                 0.4805           1055.0257       342.19
    DT2 DT2_rPPC_rCCG_3468um_1252um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        575713                 True                 0.9223           1029.4623       397.52
    DT2 DT2_rPPC_rCCG_3540um_1288um_2016   wheel_alternation_task               pixels             pixels              0.0333       0.0333                             0                 True                 0.8333            991.4633       393.74
    DT2 DT2_rPPC_rCCG_3540um_1288um_2016   wheel_alternation_task               pixels             pixels              0.0000       0.0333                        218643                 True                 0.6671           1059.5769       369.89
    DT2 DT2_rPPC_rCCG_3612um_1360um_2016   wheel_alternation_task               pixels             pixels              0.0300       0.0333                         12865                 True                 0.0695            974.7727       418.39
    DT5      20161011_972um_1224um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            215.0444         1.38
    DT5     20161014_1296um_1476um_merge central_alternation_task                    m                 cm              0.0084       0.0083                             0                 True                 0.0000            220.1540         1.01
    DT5     20161015_1368um_1476um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            219.8351         1.02
    DT5     20161016_1368um_1476um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            221.8106         1.11
    DT5     20161018_1552um_2304um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            224.0515         1.08
    DT5 20161019_1624um_2340um_161019_09 central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            221.5655         1.04
    DT5 20161020_1768um_2376um_161020_10 central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            218.9629         1.11
    DT5     20161021_1840um_2412um_merge              linear_task                    m                 cm              0.0083       0.0083                             0                 True                 0.8735            131.2191         1.44
    DT5 20161023_1872um_2448um_161023_12 central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.4663            219.5207         0.97
    DT5     20161025_1944um_2232um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.8670            224.3449         1.47
    DT5     20161026_1944um_2232um_merge              linear_task                    m                 cm              0.0083       0.0083                             0                 True                 0.8977            129.7367         1.39
    DT5 20161027_1944um_2232um_161027_19 central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0071            220.6123         1.01
    DT5 20161030_2052um_2232um_161030_11 central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.8982            219.3806         1.08
    DT5 20161031_2088um_2232um_161031_10   wheel_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.9143            222.8863         1.13
    DT5     20161101_2088um_2232um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.0000            220.8995         1.43
    DT5     20161104_2124um_2232um_merge central_alternation_task                    m                 cm              0.0083       0.0083                             0                 True                 0.8465            225.6465         1.12
    DT7 20170315_288um_0um_170315_191240   wheel_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0482            273.5789      1024.96
    DT7         20170317_288um_0um_merge              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            129.1852      1599.63
    DT7 20170318_288um_0um_170318_115923   wheel_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            273.1420      1105.68
    DT7         20170320_432um_0um_merge   wheel_alternation_task                   mm                 cm              0.0083       0.0357                             0                 True                 0.0013            278.3766      1506.73
    DT7 20170321_216um_0um_170321_120259   wheel_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            276.9192      1431.41
    DT7 20170324_576um_144um_170324_1239   wheel_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            273.7343       998.76
    DT7 20170325_576um_360um_170325_1255   wheel_alternation_task                    m                 cm              0.0083       0.0084                             0                 True                 0.0000            282.6229         1.06
    DT7       20170401_864um_936um_merge              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            153.0244      1577.03
    DT7 20170412_1440um_1170um_170412_10    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            256.7746      1583.51
    DT8           20170125_0um_0um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            222.1212         1.14
    DT8          20170128_0um_72um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            231.7116         1.26
    DT8        20170201_72um_432um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            224.3831         1.30
    DT8 20170202_72um_576um_170202_09203 central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            229.4058         1.28
    DT8       20170206_72um_1872um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            224.3654      1181.80
    DT8      20170207_144um_1944um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            221.6774      1196.79
    DT8      20170211_144um_1944um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            232.2945         1.31
    DT8 20170214_216um_1944um_170214_102 central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            223.8942      1036.90
    DT8 20170215_216um_1944um_170215_140 central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            226.1991      1178.78
    DT8      20170216_216um_1944um_merge    both_alternation_task                   mm                 cm              0.0084       0.0083                             0                 True                 0.0000            233.6049      1179.19
    DT8      20170217_216um_1944um_merge    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            239.0856         1.22
    DT8 20170218_216um_1944um_170218_114    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            248.3878         1.15
    DT8 20170221_324um_1944um_170221_101 central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            221.5746      1142.28
    DT8 20170224_324um_2088um_170224_101 central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            232.6887      1231.67
    DT8 20170305_468um_2088um_170305_135 central_alternation_task                   mm                 cm              0.0084       0.0083                             0                 True                 0.0000            227.1590      1182.31
    DT8 20170306_468um_2088um_170306_113    both_alternation_task                   mm                 cm              0.0084       0.0083                             0                 True                 0.0000            253.3195         1.18
    DT8      20170308_612um_2088um_merge    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            272.3338      1240.09
    DT9           20170429_0um_0um_merge central_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            230.3910      1074.36
    DT9           20170430_0um_0um_merge   wheel_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            289.4971      1216.18
    DT9 20170501_216um_0um_170501_112210    both_alternation_task                   mm                 cm              0.0083       0.0092                             0                 True                 0.0000            133.7079      1742.27
    DT9         20170502_288um_0um_merge              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            150.8991      1736.98
    DT9         20170504_396um_0um_merge              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            170.2450      1736.25
    DT9         20170505_396um_0um_merge    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            269.9068      1103.78
    DT9 20170506_468um_36um_170506_11183    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            244.7696      1043.45
    DT9        20170507_468um_36um_merge              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            145.1550      1773.56
    DT9 20170509_468um_36um_170509_10345    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            225.0518      1103.24
    DT9       20170518_828um_864um_merge    both_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            248.0722      1142.68
    DT9       20170519_864um_900um_merge   wheel_alternation_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            224.3662      1621.40
    DT9 20170521_900um_936um_170521_1256              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            132.3526      1734.94
    DT9 20170522_900um_936um_170522_1511              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            161.2094      1657.93
    DT9 20170525_900um_936um_170525_1501              linear_task                   mm                 cm              0.0083       0.0083                             0                 True                 0.0000            150.5245      1704.10

Files whose stated position unit disagrees with the values: 8: ['20170125_0um_0um_merge', '20170128_0um_72um_merge', '20170201_72um_432um_merge', '20170202_72um_576um_170202_09203', '20170211_144um_1944um_merge', '20170217_216um_1944um_merge', '20170218_216um_1944um_170218_114', '20170306_468um_2088um_170306_113']
Files whose third position column equals the second: 67 of 67
Files with repeated or decreasing position timestamps: ['DT2_rPPC_rCCG_3396um_1180um_2016', 'DT2_rPPC_rCCG_3396um_1180um_2016', 'DT2_rPPC_rCCG_3468um_1216um_2016', 'DT2_rPPC_rCCG_3468um_1216um_2016', 'DT2_rPPC_rCCG_3468um_1216um_2016', 'DT2_rPPC_rCCG_3468um_1252um_2016', 'DT2_rPPC_rCCG_3540um_1288um_2016', 'DT2_rPPC_rCCG_3612um_1360um_2016']

Position is stated in m, mm or pixels. Eight DT8 files state mm but hold values spanning about 1.1 to 1.3, which are metres (a maze of about a metre across; the same rat's other files span 1000 to 1200 mm). The unit used here is inferred from the extent: below 10 the values are taken as metres, otherwise as millimetres; sub-DT2 positions stay in pixels, with no scale given. In every file the third position column (z) is a copy of the second (y). In eight of the eleven sub-DT2 files position timestamps repeat or go back (the count of such steps is printed), so the time per sample is taken as the session's span over its sample count, which gives 33.3 ms (30 Hz) in every sub-DT2 file. The median path of a trial is 2.2 to 2.9 m on the alternation mazes and 1.3 to 1.7 m on the linear track (outside sub-DT2), against the paper's maze of about 3.2 m; the paper gives no other maze dimensions in the main text.

In [5]:
tr = S[["subject", "name", "task", "n_trials", "trial_s_median", "trial_types", "directions", "conditions_used",
        "trials_without_positions", "trials_after_position_end"]]
print(tr.to_string(index=False))
print("\nTrial types:", sorted({str(t) for x in S.trial_types for t in x}), "| directions:", sorted({str(t) for x in S.directions for t in x}))
print("Files whose trials carry no type or direction:", S[S.trial_types.apply(lambda x: x == [""])].name.tolist())
print("Conditions with at least 10 trials, all files:", int(S.conditions_used.sum()))
subject                             name                     task  n_trials  trial_s_median                              trial_types                     directions  conditions_used  trials_without_positions  trials_after_position_end
    DT2 DT2_rPPC_rCCG_3324um_1000um_2016   wheel_alternation_task        69        4.933333                      [wheel alternation] [clockwise, counter-clockwise]                4                         0                          0
    DT2 DT2_rPPC_rCCG_3324um_1144um_2016   wheel_alternation_task        84        4.683333                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT2 DT2_rPPC_rCCG_3396um_1180um_2016   wheel_alternation_task        71        4.500000                      [wheel alternation] [clockwise, counter-clockwise]                2                         0                          0
    DT2 DT2_rPPC_rCCG_3396um_1180um_2016   wheel_alternation_task       121        5.233281                      [wheel alternation] [clockwise, counter-clockwise]                4                         0                          1
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016   wheel_alternation_task       100        4.650000                      [wheel alternation] [clockwise, counter-clockwise]                5                         0                          0
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016   wheel_alternation_task       115        4.300000                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016   wheel_alternation_task       113        4.500000                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT2 DT2_rPPC_rCCG_3468um_1252um_2016   wheel_alternation_task       134        4.400000                      [wheel alternation] [clockwise, counter-clockwise]                5                         0                          0
    DT2 DT2_rPPC_rCCG_3540um_1288um_2016   wheel_alternation_task       207        4.733333                      [wheel alternation] [clockwise, counter-clockwise]                7                         0                          0
    DT2 DT2_rPPC_rCCG_3540um_1288um_2016   wheel_alternation_task       106        4.500000                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT2 DT2_rPPC_rCCG_3612um_1360um_2016   wheel_alternation_task        30        3.590000                      [wheel alternation] [clockwise, counter-clockwise]                0                         0                          0
    DT5      20161011_972um_1224um_merge central_alternation_task       186        3.733333                    [central alternation] [clockwise, counter-clockwise]                7                         0                          1
    DT5     20161014_1296um_1476um_merge central_alternation_task       151        4.433333                    [central alternation] [clockwise, counter-clockwise]                5                         0                          1
    DT5     20161015_1368um_1476um_merge central_alternation_task       115        4.125000                    [central alternation] [clockwise, counter-clockwise]                5                         0                          1
    DT5     20161016_1368um_1476um_merge central_alternation_task        33        4.350000                    [central alternation] [clockwise, counter-clockwise]                2                         0                          1
    DT5     20161018_1552um_2304um_merge central_alternation_task       213        3.791667                    [central alternation] [clockwise, counter-clockwise]                7                         0                          1
    DT5 20161019_1624um_2340um_161019_09 central_alternation_task       238        3.804167                    [central alternation] [clockwise, counter-clockwise]                8                         0                          1
    DT5 20161020_1768um_2376um_161020_10 central_alternation_task       245        3.716667                    [central alternation] [clockwise, counter-clockwise]                6                         0                          1
    DT5     20161021_1840um_2412um_merge              linear_task        54        2.354167                                       []                             []                2                         0                          0
    DT5 20161023_1872um_2448um_161023_12 central_alternation_task       138        3.737500                    [central alternation] [clockwise, counter-clockwise]                7                         0                          0
    DT5     20161025_1944um_2232um_merge central_alternation_task       117        4.091667                    [central alternation] [clockwise, counter-clockwise]                4                         0                          0
    DT5     20161026_1944um_2232um_merge              linear_task        57        1.981250                                       []                             []                2                         0                          1
    DT5 20161027_1944um_2232um_161027_19 central_alternation_task       190        3.641667                    [central alternation] [clockwise, counter-clockwise]                7                         0                          0
    DT5 20161030_2052um_2232um_161030_11 central_alternation_task       225        3.633333                    [central alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT5 20161031_2088um_2232um_161031_10   wheel_alternation_task       185        3.508333                      [wheel alternation] [clockwise, counter-clockwise]                7                         0                          0
    DT5     20161101_2088um_2232um_merge central_alternation_task        76        3.433333                    [central alternation] [clockwise, counter-clockwise]                2                         0                          1
    DT5     20161104_2124um_2232um_merge central_alternation_task       150        4.677995                    [central alternation] [clockwise, counter-clockwise]                8                         0                          1
    DT7 20170315_288um_0um_170315_191240   wheel_alternation_task       123        4.250000                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT7         20170317_288um_0um_merge              linear_task        76        2.033333                                       []                             []                2                         0                          0
    DT7 20170318_288um_0um_170318_115923   wheel_alternation_task       252        4.283333                      [wheel alternation] [clockwise, counter-clockwise]                7                         0                          0
    DT7         20170320_432um_0um_merge   wheel_alternation_task       326        3.916667                      [wheel alternation] [clockwise, counter-clockwise]                8                         0                          0
    DT7 20170321_216um_0um_170321_120259   wheel_alternation_task       249        4.418750                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          1
    DT7 20170324_576um_144um_170324_1239   wheel_alternation_task       121        4.550000                      [wheel alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT7 20170325_576um_360um_170325_1255   wheel_alternation_task       239        3.958333                      [wheel alternation] [clockwise, counter-clockwise]                7                         0                          0
    DT7       20170401_864um_936um_merge              linear_task        81        2.008333                                       []                             []                2                         0                          0
    DT7 20170412_1440um_1170um_170412_10    both_alternation_task        76        3.637338 [central alternation, wheel alternation] [clockwise, counter-clockwise]                2                         0                          0
    DT8           20170125_0um_0um_merge central_alternation_task        17        4.416475                    [central alternation] [clockwise, counter-clockwise]                1                         0                          0
    DT8          20170128_0um_72um_merge central_alternation_task        71        3.666667                    [central alternation] [clockwise, counter-clockwise]                4                         0                          1
    DT8        20170201_72um_432um_merge central_alternation_task       137        3.583333                    [central alternation] [clockwise, counter-clockwise]                4                         0                          1
    DT8 20170202_72um_576um_170202_09203 central_alternation_task       116        3.761924                    [central alternation] [clockwise, counter-clockwise]                4                         0                          0
    DT8       20170206_72um_1872um_merge central_alternation_task       146        3.404167                    [central alternation] [clockwise, counter-clockwise]                5                         0                          1
    DT8      20170207_144um_1944um_merge central_alternation_task       174        3.208333                                       []                             []                4                         0                          1
    DT8      20170211_144um_1944um_merge central_alternation_task        74        3.391667                    [central alternation] [clockwise, counter-clockwise]                4                         0                          1
    DT8 20170214_216um_1944um_170214_102 central_alternation_task       242        3.749825                    [central alternation] [clockwise, counter-clockwise]                6                         0                          0
    DT8 20170215_216um_1944um_170215_140 central_alternation_task        72        3.329167                    [central alternation] [clockwise, counter-clockwise]                3                         0                          1
    DT8      20170216_216um_1944um_merge    both_alternation_task       264        3.497641 [central alternation, wheel alternation] [clockwise, counter-clockwise]               10                         0                          1
    DT8      20170217_216um_1944um_merge    both_alternation_task       226        3.579167 [central alternation, wheel alternation] [clockwise, counter-clockwise]                5                         0                          1
    DT8 20170218_216um_1944um_170218_114    both_alternation_task       254        3.983163 [central alternation, wheel alternation] [clockwise, counter-clockwise]                9                         0                          0
    DT8 20170221_324um_1944um_170221_101 central_alternation_task       199        3.279948 [central alternation, wheel alternation] [clockwise, counter-clockwise]               12                         0                          1
    DT8 20170224_324um_2088um_170224_101 central_alternation_task       210        3.395955                                       []                             []                7                         0                          1
    DT8 20170305_468um_2088um_170305_135 central_alternation_task       209        3.353125                    [central alternation] [clockwise, counter-clockwise]                6                         0                          1
    DT8 20170306_468um_2088um_170306_113    both_alternation_task       234        4.408333 [central alternation, wheel alternation] [clockwise, counter-clockwise]                8                         0                          1
    DT8      20170308_612um_2088um_merge    both_alternation_task        92        3.799825 [central alternation, wheel alternation] [clockwise, counter-clockwise]                3                         0                          0
    DT9           20170429_0um_0um_merge central_alternation_task       160        3.925000 [central alternation, wheel alternation] [clockwise, counter-clockwise]                8                         0                          1
    DT9           20170430_0um_0um_merge   wheel_alternation_task       159        4.391667                      [wheel alternation] [clockwise, counter-clockwise]                5                         0                          1
    DT9 20170501_216um_0um_170501_112210    both_alternation_task       175        4.750000 [central alternation, wheel alternation] [clockwise, counter-clockwise]                0                         0                          1
    DT9         20170502_288um_0um_merge              linear_task        60        2.033333                                       []                             []                2                         0                          0
    DT9         20170504_396um_0um_merge              linear_task        56        2.433225                                       []                             []                2                         0                          0
    DT9         20170505_396um_0um_merge    both_alternation_task       221        4.125000 [central alternation, wheel alternation] [clockwise, counter-clockwise]               10                         0                          1
    DT9 20170506_468um_36um_170506_11183    both_alternation_task       293        3.933333 [central alternation, wheel alternation] [clockwise, counter-clockwise]               13                         0                          1
    DT9        20170507_468um_36um_merge              linear_task        62        1.712500                                       []                             []                2                         0                          0
    DT9 20170509_468um_36um_170509_10345    both_alternation_task       263        3.541667 [central alternation, wheel alternation] [clockwise, counter-clockwise]                9                         0                          1
    DT9       20170518_828um_864um_merge    both_alternation_task       315        3.683333 [central alternation, wheel alternation] [clockwise, counter-clockwise]               11                         0                          1
    DT9       20170519_864um_900um_merge   wheel_alternation_task        85        3.208333                    [central alternation] [clockwise, counter-clockwise]                4                         0                          1
    DT9 20170521_900um_936um_170521_1256              linear_task        93        1.641600                                       []                             []                2                         0                          0
    DT9 20170522_900um_936um_170522_1511              linear_task       105        2.108333                                       []                             []                2                         0                          0
    DT9 20170525_900um_936um_170525_1501              linear_task        57        1.916667                                       []                             []                2                         0                          0

Trial types: ['', 'central alternation', 'wheel alternation'] | directions: ['', 'clockwise', 'counter-clockwise']
Files whose trials carry no type or direction: ['20161021_1840um_2412um_merge', '20161026_1944um_2232um_merge', '20170317_288um_0um_merge', '20170401_864um_936um_merge', '20170207_144um_1944um_merge', '20170224_324um_2088um_170224_101', '20170502_288um_0um_merge', '20170504_396um_0um_merge', '20170507_468um_36um_merge', '20170521_900um_936um_170521_1256', '20170522_900um_936um_170522_1511', '20170525_900um_936um_170525_1501']
Conditions with at least 10 trials, all files: 349

The trials table has trial_type (central or wheel alternation) and direction (clockwise or counter-clockwise) for the alternation tasks, and only start and stop times on the linear track and in two DT8 alternation files (20170207 and 20170224). Trials last a median of 1.6 to 5.2 s. The paper's trial conditions are not in the dandiset; the conditions formed here (type, direction, start and end site) give 0 to 13 conditions of at least 10 trials per file. DT9 20170501 has none: its trials do not start or end at common sites (see the clock check below).

In [6]:
lf = S[["subject", "name", "lfp_shape", "lfp_chunks", "lfp_rate", "lfp_start", "lfp_conversion", "hpc_channels_from",
        "n_hpc_channels", "n_ls_channels", "theta_channel", "ls_channel"]].copy()
sel = [d if isinstance(d, dict) else {} for d in S.theta_channel_selection]
lf["theta_label"] = [d.get("label") for d in sel]
lf["theta_ratio"] = [d.get("theta_ratio", np.nan) for d in sel]
lf["median_ratio"] = [d.get("median_theta_ratio", np.nan) for d in sel]
lf["psd_peak_hz"] = [d.get("psd_peak_hz", np.nan) for d in sel]
lf["theta_contrast"] = [d.get("theta_peak_over_neighbours", np.nan) for d in sel]
lf["lfp_conversion"] = lf.lfp_conversion.map("{:.3g}".format)
S["theta_ratio"], S["theta_label"] = lf.theta_ratio.values, lf.theta_label.values
print(lf.round(2).to_string(index=False))
print("\nLFP sampling rates:", S.lfp_rate.unique(), "| starting times:", S.lfp_start.unique())
print("Files without a hippocampal channel (no theta reference):", S[~S.has_theta].name.tolist())
print("Hippocampal channel labels per file:", pd.Series([tuple(x) for x in S.hpc_channel_labels]).value_counts().to_dict(),
      "| files with both hpc and ca3 channels:", int(sum(("hpc" in x) and ("ca3" in x) for x in S.hpc_channel_labels)))
print("Label of the theta channel, files:", lf.theta_label.value_counts(dropna=False).to_dict())
q = lf[lf.theta_ratio.notna()].groupby("subject").agg(files=("name", "size"), ratio_below_1=("theta_ratio", lambda x: int((x < 1).sum())),
                                                       ratio_min=("theta_ratio", "min"), ratio_max=("theta_ratio", "max"),
                                                       psd_peak_min=("psd_peak_hz", "min"), psd_peak_max=("psd_peak_hz", "max"),
                                                       contrast_median=("theta_contrast", "median"))
print("\nTheta channel per subject: 6-9 Hz over 1-4 Hz power, frequency of the spectral peak between 2 and 20 Hz, and the")
print("6-9 Hz peak over the mean power at 2-5 and 11-15 Hz (theta_contrast):")
print(q.round(2).to_string())
subject                             name       lfp_shape  lfp_chunks  lfp_rate  lfp_start lfp_conversion   hpc_channels_from  n_hpc_channels  n_ls_channels  theta_channel  ls_channel theta_label  theta_ratio  median_ratio  psd_peak_hz  theta_contrast
    DT2 DT2_rPPC_rCCG_3324um_1000um_2016 (32632065, 128)  (500, 128)    1250.0        0.0       1.95e-07 groups of the units               0             52            NaN         NaN         NaN          NaN           NaN          NaN             NaN
    DT2 DT2_rPPC_rCCG_3324um_1144um_2016 (27225225, 128) (212697, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64          101.0         6.0     unknown         8.49          7.51         8.50           32.91
    DT2 DT2_rPPC_rCCG_3396um_1180um_2016 (17010855, 128) (132897, 1)    1250.0        0.0       1.95e-07 groups of the units              64             52          111.0         6.0     unknown         9.13          8.84         9.00           94.45
    DT2 DT2_rPPC_rCCG_3396um_1180um_2016 (26425350, 128) (206448, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64          123.0         6.0     unknown         8.97          7.58         8.75           80.22
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016 (19182015, 128) (149859, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64           73.0         6.0     unknown        12.89         12.72         8.75          115.84
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016 (11191860, 128)  (87436, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64           98.0         6.0     unknown        12.66         12.64         8.50          131.01
    DT2 DT2_rPPC_rCCG_3468um_1216um_2016 (21440742, 128) (167505, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64           83.0         6.0     unknown         3.53          3.37         8.00           20.45
    DT2 DT2_rPPC_rCCG_3468um_1252um_2016 (29556630, 128) (230911, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64          113.0         6.0     unknown         7.58          7.24         9.00          131.59
    DT2 DT2_rPPC_rCCG_3540um_1288um_2016 (20994795, 128) (164021, 1)    1250.0        0.0       1.95e-07 groups of the units              64             64          113.0         6.0     unknown         8.66          8.26         9.00           99.03
    DT2 DT2_rPPC_rCCG_3540um_1288um_2016 (14165685, 128) (110669, 1)    1250.0        0.0       1.95e-07 groups of the units              60             60          113.0         6.0     unknown        12.24         11.80         8.75          137.00
    DT2 DT2_rPPC_rCCG_3612um_1360um_2016  (2054160, 128)  (48144, 3)    1250.0        0.0       1.95e-07 groups of the units              60             60          111.0         6.0     unknown         9.10          7.54         8.75           81.35
    DT5      20161011_972um_1224um_merge  (41328630, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           41.0         4.0         hpc         2.27          2.26         8.75           25.91
    DT5     20161014_1296um_1476um_merge  (25007625, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           51.0         4.0         hpc         1.30          1.26         9.50           15.52
    DT5     20161015_1368um_1476um_merge  (21792600, 96) (227006, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           62.0         4.0         hpc         0.49          0.32         9.50            4.31
    DT5     20161016_1368um_1476um_merge   (3984120, 96)  (83002, 2)    1250.0        0.0       1.95e-07    electrodes table              64             32           32.0         4.0         hpc         0.74          0.71         9.50            8.11
    DT5     20161018_1552um_2304um_merge  (38386485, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           83.0         4.0         ca3         0.60          0.49         9.50            2.54
    DT5 20161019_1624um_2340um_161019_09  (29323260, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           83.0         4.0         ca3         0.48          0.44         9.50            2.23
    DT5 20161020_1768um_2376um_161020_10  (33005295, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           83.0         4.0         hpc         0.46          0.40         9.75            3.25
    DT5     20161021_1840um_2412um_merge  (35784945, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           83.0         4.0         ca3         0.72          0.70         2.00            3.55
    DT5 20161023_1872um_2448um_161023_12   (5626440, 96) (117216, 2)    1250.0        0.0       1.95e-07    electrodes table              64             32           94.0         4.0         hpc         0.97          0.63         9.00           10.19
    DT5     20161025_1944um_2232um_merge  (33168195, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           84.0         4.0         hpc         0.63          0.59         2.50            2.65
    DT5     20161026_1944um_2232um_merge  (34552530, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           95.0         4.0         hpc         0.40          0.40         8.75            3.83
    DT5 20161027_1944um_2232um_161027_19   (2841120, 96)  (59190, 2)    1250.0        0.0       1.95e-07    electrodes table              64             32           80.0         4.0         hpc         0.62          0.59         9.25            3.94
    DT5 20161030_2052um_2232um_161030_11  (31125000, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           81.0         4.0         hpc         0.62          0.57         9.00            3.31
    DT5 20161031_2088um_2232um_161031_10  (39212055, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           95.0         4.0         ca3         0.33          0.33         2.00            1.99
    DT5     20161101_2088um_2232um_merge  (28839664, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           81.0         4.0         ca3         0.39          0.33         9.75            1.30
    DT5     20161104_2124um_2232um_merge  (30052035, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           81.0         4.0         ca3         0.59          0.55         9.25            3.50
    DT7 20170315_288um_0um_170315_191240  (2680965, 128)  (62835, 3)    1250.0        0.0       1.95e-07    electrodes table              64             23            0.0        81.0         hpc         3.00          2.86         9.00           29.14
    DT7         20170317_288um_0um_merge (30896487, 128) (241378, 1)    1250.0        0.0       1.95e-07    electrodes table              64             64           59.0        96.0         hpc         4.38          3.95         9.00           16.32
    DT7 20170318_288um_0um_170318_115923 (35846370, 128)  (500, 128)    1250.0        0.0       1.95e-07    electrodes table              63             24           59.0        63.0         hpc         2.64          1.80         9.50           15.23
    DT7         20170320_432um_0um_merge (37460925, 128)  (500, 128)    1250.0        0.0       1.95e-07    electrodes table              64             23           49.0        80.0         hpc         2.86          1.89         9.25           78.81
    DT7 20170321_216um_0um_170321_120259 (45056880, 128)  (500, 128)    1250.0        0.0       1.95e-07    electrodes table              63             24           55.0        63.0         hpc         2.78          2.46         9.25           40.24
    DT7 20170324_576um_144um_170324_1239 (12303900, 128)  (96124, 1)    1250.0        0.0       1.95e-07    electrodes table              63             24           22.0        63.0         hpc        10.37          9.55         8.00           68.72
    DT7 20170325_576um_360um_170325_1255 (37256670, 128)  (500, 128)    1250.0        0.0       1.95e-07    electrodes table              64             21           49.0        87.0         hpc         1.19          1.18         9.50           17.84
    DT7       20170401_864um_936um_merge (18219375, 128) (142338, 1)    1250.0        0.0       1.95e-07    electrodes table              63             24           17.0        96.0         hpc         0.71          0.68         8.75            5.32
    DT7 20170412_1440um_1170um_170412_10 (33977565, 128)  (500, 128)    1250.0        0.0       1.95e-07    electrodes table              63             17           24.0       110.0         hpc         1.03          1.01         8.00            8.88
    DT8           20170125_0um_0um_merge  (29268585, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           35.0         4.0         hpc         0.22          0.21         2.00            1.27
    DT8          20170128_0um_72um_merge  (24716295, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           55.0         4.0         hpc         2.68          2.67         8.75           18.17
    DT8        20170201_72um_432um_merge  (17565525, 96) (182974, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           95.0         4.0         hpc         1.51          1.28         9.25           10.98
    DT8 20170202_72um_576um_170202_09203  (24669945, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           94.0         4.0         hpc         1.79          1.74         7.75            6.64
    DT8       20170206_72um_1872um_merge  (40832730, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           83.0         4.0         hpc         1.85          1.57         8.75           22.43
    DT8      20170207_144um_1944um_merge  (35203230, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           85.0         4.0         hpc         0.95          0.81         9.25           17.01
    DT8      20170211_144um_1944um_merge  (24766290, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           85.0         4.0         hpc         1.56          1.16         8.75           15.64
    DT8 20170214_216um_1944um_170214_102  (25032105, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           90.0         4.0         hpc         1.04          0.80         8.75           10.76
    DT8 20170215_216um_1944um_170215_140  (28069875, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           71.0         4.0         hpc         1.50          1.37         8.50           11.69
    DT8      20170216_216um_1944um_merge  (27245835, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           74.0         4.0         hpc         0.76          0.45         8.75           13.08
    DT8      20170217_216um_1944um_merge  (26107605, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           83.0         4.0         hpc         1.18          1.00         9.25            9.95
    DT8 20170218_216um_1944um_170218_114  (22726485, 96) (236734, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           89.0         4.0         hpc         1.60          1.20         8.50            9.19
    DT8 20170221_324um_1944um_170221_101  (25058835, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           91.0         4.0         hpc         1.33          1.32         8.75           12.94
    DT8 20170224_324um_2088um_170224_101  (39324735, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           81.0         4.0         hpc         1.30          1.16         9.00           10.30
    DT8 20170305_468um_2088um_170305_135  (20643750, 96) (215039, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           79.0         4.0         hpc         1.16          0.41         9.25            7.54
    DT8 20170306_468um_2088um_170306_113  (36137382, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           91.0         4.0         hpc         0.49          0.44         9.25            4.66
    DT8      20170308_612um_2088um_merge  (37364535, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           77.0         4.0         hpc         0.97          0.37         9.25            8.20
    DT9           20170429_0um_0um_merge  (32214150, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           33.0         4.0         hpc         5.60          4.80         8.50           39.10
    DT9           20170430_0um_0um_merge   (6280380, 96)  (65420, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           48.0         4.0         hpc         5.46          4.62         8.75           41.23
    DT9 20170501_216um_0um_170501_112210  (40590585, 96)   (500, 96)    1250.0        0.0       1.95e-07 groups of the units              64             32           93.0         4.0     unknown         4.98          4.84         8.25           33.15
    DT9         20170502_288um_0um_merge  (43905780, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           40.0         4.0         hpc        10.79          8.16         7.75           42.27
    DT9         20170504_396um_0um_merge  (43722495, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           43.0         4.0         hpc         3.01          3.00         8.75           23.20
    DT9         20170505_396um_0um_merge  (34992135, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           40.0         4.0         hpc         4.42          3.77         8.75           52.01
    DT9 20170506_468um_36um_170506_11183  (33079905, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           48.0         4.0         hpc         4.61          4.38         8.75           58.25
    DT9        20170507_468um_36um_merge  (41310810, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           48.0         4.0         hpc        17.41          7.41         7.25           41.13
    DT9 20170509_468um_36um_170509_10345  (33042915, 96)   (500, 96)    1250.0        0.0       1.95e-07 groups of the units              40             24           43.0         4.0     unknown         5.92          5.70         8.25           37.59
    DT9       20170518_828um_864um_merge  (41010480, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           54.0         4.0         ca3         0.59          0.58         9.00            4.38
    DT9       20170519_864um_900um_merge  (30231900, 96)   (500, 96)    1250.0        0.0       1.95e-07    electrodes table              64             32           54.0         4.0         ca3         0.66          0.63         9.00           10.20
    DT9 20170521_900um_936um_170521_1256  (20646270, 96) (215065, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           52.0         4.0         ca3         2.61          2.60         7.75           16.74
    DT9 20170522_900um_936um_170522_1511   (8425305, 96)  (87763, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           50.0         4.0         ca3         1.81          1.81         7.75           10.46
    DT9 20170525_900um_936um_170525_1501   (8969220, 96)  (93429, 1)    1250.0        0.0       1.95e-07    electrodes table              64             32           48.0         4.0         ca3         1.22          1.11         8.75           11.02

LFP sampling rates: [1250.] | starting times: [0.]
Files without a hippocampal channel (no theta reference): ['DT2_rPPC_rCCG_3324um_1000um_2016']
Hippocampal channel labels per file: {('hpc',): 43, ('unknown',): 12, ('ca3',): 11, (): 1} | files with both hpc and ca3 channels: 0
Label of the theta channel, files: {'hpc': 43, 'unknown': 12, 'ca3': 11, nan: 1}

Theta channel per subject: 6-9 Hz over 1-4 Hz power, frequency of the spectral peak between 2 and 20 Hz, and the
6-9 Hz peak over the mean power at 2-5 and 11-15 Hz (theta_contrast):
         files  ratio_below_1  ratio_min  ratio_max  psd_peak_min  psd_peak_max  contrast_median
subject                                                                                         
DT2         10              0       3.53      12.89          8.00          9.00            96.74
DT5         16             14       0.33       2.27          2.00          9.75             3.52
DT7          9              1       0.71      10.37          8.00          9.50            17.84
DT8         17              5       0.22       2.68          2.00          9.25            10.76
DT9         14              2       0.59      17.41          7.25          9.00            35.37

The LFP is stored at 1250 Hz from time 0 in every file, as the paper's code assumes (phases(round(t*1250))). 42 files chunk it as 500 samples by all channels, so the analysis reads only the trials (with 1 s on each side), two channels at a time. One file (DT2, 20160217) has no hippocampal units or labelled hippocampal channels, so it has no theta reference: its LS units are counted, but not decoded.

No file has both hpc and ca3 channels: the hippocampal channels of a file carry one label (43 files hpc, 11 ca3, and 12 unknown, taken from the groups of the hpc units). In the 11 files with ca3 channels the theta reference is therefore a CA3 channel. The paper's code does the same for a session without a CA1 channel (it uses sessionInfo.ca1, else sessionInfo.ca3), but the paper's Figure 6A counts 63 CA1 and 19 CA3 sessions, so its sessions had CA1 channels that are not labelled here.

The theta reference is weak in DT5. On the chosen channel, 6 to 9 Hz power is below 1 to 4 Hz power in 14 of 16 DT5 files (ratio 0.33 to 2.27), and the 6 to 9 Hz peak stands a median 3.5 times above the power at 2 to 5 and 11 to 15 Hz, against medians of 11 to 97 in the other rats. The spectral peak between 2 and 20 Hz is at 2 to 2.5 Hz in three DT5 files and one DT8 file, and at 7.25 to 9.75 Hz in all others. The phase claims are repeated on the sessions whose ratio is above 1.

In [7]:
lags = list(lshpc.TRIAL_SHIFTS_S)
sp = pd.DataFrame([r["summary"]["clock_trial_speed"] for r in results], index=S.name)
sp_peak = sp.idxmax(axis=1)
print("Mean running speed (position units per s) inside the trial windows shifted by each lag (s); peak lag per file:")
print(pd.concat([sp.round(1), sp_peak.rename("peak")], axis=1).to_string())
print("\nPeak lag of speed inside trials, files per lag:", sp_peak.value_counts().sort_index().to_dict())
ratio = sp[0.0] / sp[[-3.0, 3.0]].mean(axis=1)
print("Speed at lag 0 over speed at +-3 s, median", round(float(ratio.median()), 2), "| range", round(float(ratio.min()), 2), "to", round(float(ratio.max()), 2))

lfp_lags = list(lshpc.LFP_LAGS_MS)
lk = pd.DataFrame([r.get("clock_lfp", {}) for r in results], index=S.name)
ok = lk.notna().all(axis=1)
lk_peak = lk[ok].idxmax(axis=1)
print("\nTheta phase locking (mean resultant length) of hippocampal spikes, LFP shifted by each lag (ms):")
print(pd.concat([lk[ok].round(3), lk_peak.rename("peak")], axis=1).to_string())
print("Files per peak lag (ms):", lk_peak.value_counts().sort_index().to_dict())
print("Locking at 0 ms over locking at +-200 ms, median",
      round(float((lk[ok][0] / lk[ok][[-200, 200]].mean(axis=1)).median()), 2))

rt = pd.DataFrame([r["summary"]["clock_trial_rate"] or {} for r in results], index=S.name).dropna()
rt_peak = rt.idxmax(axis=1)
print("\nMean firing rate of all units in the trial windows shifted by each lag, files per peak lag:",
      rt_peak.value_counts().sort_index().to_dict())
Mean running speed (position units per s) inside the trial windows shifted by each lag (s); peak lag per file:
                                   -3.0   -2.0   -1.0   -0.5    0.0    0.5    1.0    2.0    3.0   peak
name                                                                                                  
DT2_rPPC_rCCG_3324um_1000um_2016  109.2  146.3  187.1  206.9  218.6  215.0  203.4  163.3  121.2    0.0
DT2_rPPC_rCCG_3324um_1144um_2016  112.3  150.2  190.9  210.5  221.5  219.0  204.1  159.1  117.2    0.0
DT2_rPPC_rCCG_3396um_1180um_2016   97.7  138.8  183.5  204.7  225.5  226.2  215.9  171.6  126.2    0.5
DT2_rPPC_rCCG_3396um_1180um_2016   60.6   77.0  107.8  125.6  142.7  160.9  172.6  164.3  134.6    1.0
DT2_rPPC_rCCG_3468um_1216um_2016   96.3  134.8  180.9  202.9  220.5  221.1  211.9  168.0  122.9    0.5
DT2_rPPC_rCCG_3468um_1216um_2016   92.7  137.8  186.0  208.9  228.9  227.0  215.1  165.6  116.5    0.0
DT2_rPPC_rCCG_3468um_1216um_2016  106.5  142.3  184.9  205.5  217.1  214.2  199.9  154.5  114.5    0.0
DT2_rPPC_rCCG_3468um_1252um_2016   90.8  133.6  181.5  204.0  224.6  225.6  215.3  169.0  121.6    0.5
DT2_rPPC_rCCG_3540um_1288um_2016  107.0  143.7  186.6  206.0  220.4  217.6  208.5  167.2  127.7    0.0
DT2_rPPC_rCCG_3540um_1288um_2016  110.2  148.5  193.2  215.0  227.5  225.9  212.8  168.3  126.0    0.0
DT2_rPPC_rCCG_3612um_1360um_2016  103.3  155.7  219.5  251.0  276.5  285.7  269.0  196.7  123.2    0.5
20161011_972um_1224um_merge        18.0   27.9   43.2   51.6   57.2   55.4   50.6   38.2   23.0    0.0
20161014_1296um_1476um_merge       23.9   29.8   40.1   45.8   49.5   47.8   44.3   36.0   27.7    0.0
20161015_1368um_1476um_merge       20.8   28.2   39.1   45.7   50.2   48.5   45.2   36.2   26.9    0.0
20161016_1368um_1476um_merge       21.1   28.4   41.1   47.3   51.2   49.6   46.3   36.8   25.7    0.0
20161018_1552um_2304um_merge       24.0   30.4   44.7   53.5   59.9   58.0   52.2   38.4   26.2    0.0
20161019_1624um_2340um_161019_09   21.6   29.4   43.9   52.3   58.2   56.4   51.2   38.0   24.3    0.0
20161020_1768um_2376um_161020_10   19.5   28.9   44.0   52.9   59.4   57.8   52.2   37.8   22.7    0.0
20161021_1840um_2412um_merge       18.8   23.7   38.4   48.6   58.5   58.6   50.5   27.9   15.5    0.5
20161023_1872um_2448um_161023_12   18.1   29.2   42.9   50.8   55.9   53.1   48.4   35.2   20.5    0.0
20161025_1944um_2232um_merge       21.1   28.8   40.5   47.4   52.2   50.6   46.3   34.8   24.3    0.0
20161026_1944um_2232um_merge       15.5   18.3   34.8   46.9   62.1   60.0   48.3   22.3   12.4    0.0
20161027_1944um_2232um_161027_19   20.1   31.4   46.1   54.3   58.4   55.2   49.0   34.1   20.4    0.0
20161030_2052um_2232um_161030_11   22.3   29.9   43.9   52.3   58.7   56.4   50.5   36.3   23.8    0.0
20161031_2088um_2232um_161031_10   28.6   34.3   45.6   53.8   59.5   56.9   51.4   38.6   28.8    0.0
20161101_2088um_2232um_merge       28.2   32.8   48.7   59.0   65.8   63.0   56.7   40.2   27.2    0.0
20161104_2124um_2232um_merge       23.5   28.8   39.2   44.4   47.4   45.3   41.4   32.9   26.3    0.0
20170315_288um_0um_170315_191240   27.0   37.5   52.0   59.4   64.5   62.5   57.1   43.2   31.1    0.0
20170317_288um_0um_merge           20.7   22.7   46.5   60.1   68.5   66.5   54.3   24.9   18.9    0.0
20170318_288um_0um_170318_115923   31.7   40.4   53.0   59.7   63.8   61.6   56.2   43.1   33.1    0.0
20170320_432um_0um_merge           39.1   43.8   58.0   66.6   72.0   68.9   62.1   48.0   38.8    0.0
20170321_216um_0um_170321_120259   28.8   38.6   51.8   58.9   63.9   61.4   56.0   43.2   32.3    0.0
20170324_576um_144um_170324_1239   27.4   36.4   48.7   55.2   60.6   59.9   55.6   43.3   32.2    0.0
20170325_576um_360um_170325_1255   36.0   41.0   55.8   64.5   70.0   67.3   60.9   46.4   37.5    0.0
20170401_864um_936um_merge         54.5   34.4   47.8   63.4   76.8   75.3   61.5   34.2   43.3    0.0
20170412_1440um_1170um_170412_10   27.2   33.1   52.9   64.4   72.5   70.4   61.3   38.7   29.9    0.0
20170125_0um_0um_merge             24.2   28.9   38.0   44.1   49.3   48.7   46.4   38.4   28.9    0.0
20170128_0um_72um_merge            26.6   35.3   48.5   56.7   62.4   58.7   52.4   40.2   25.4    0.0
20170201_72um_432um_merge          26.7   33.3   45.8   54.8   61.1   57.6   52.3   41.1   27.2    0.0
20170202_72um_576um_170202_09203   30.0   33.3   44.5   53.2   60.1   58.3   53.6   42.5   31.1    0.0
20170206_72um_1872um_merge         27.2   37.5   52.2   61.9   67.0   62.2   54.3   39.6   22.8    0.0
20170207_144um_1944um_merge        33.2   37.4   48.9   59.8   69.5   66.3   58.7   43.3   28.3    0.0
20170211_144um_1944um_merge        30.1   36.5   50.3   60.3   68.5   65.2   59.1   44.2   28.0    0.0
20170214_216um_1944um_170214_102   29.2   32.8   44.3   53.2   59.6   57.3   52.7   43.1   30.8    0.0
20170215_216um_1944um_170215_140   27.3   38.2   51.6   62.1   69.3   64.4   57.0   42.0   23.7    0.0
20170216_216um_1944um_merge        33.7   37.7   52.2   62.4   69.5   65.7   59.6   45.5   32.2    0.0
20170217_216um_1944um_merge        33.7   41.3   52.7   61.0   66.5   62.5   56.3   44.1   32.4    0.0
20170218_216um_1944um_170218_114   27.4   35.3   50.3   58.9   63.3   60.4   55.6   42.9   29.6    0.0
20170221_324um_1944um_170221_101   29.9   37.9   53.1   64.3   71.0   66.4   58.7   42.8   28.2    0.0
20170224_324um_2088um_170224_101   37.7   42.2   56.4   66.5   69.9   65.2   58.0   44.2   34.1    0.0
20170305_468um_2088um_170305_135   32.4   37.0   53.8   64.1   65.8   59.0   51.0   38.2   26.8    0.0
20170306_468um_2088um_170306_113   27.6   34.6   44.4   50.6   55.1   53.1   49.5   40.3   30.3    0.0
20170308_612um_2088um_merge        28.4   38.5   54.1   63.8   70.0   67.5   61.6   46.8   30.1    0.0
20170429_0um_0um_merge             29.9   33.3   44.5   52.9   58.0   55.5   50.0   39.8   29.9    0.0
20170430_0um_0um_merge             32.9   41.3   54.4   61.2   65.2   61.9   56.5   43.9   34.1    0.0
20170501_216um_0um_170501_112210   32.1   32.8   32.7   32.1   31.5   30.6   29.7   29.1   29.1   -2.0
20170502_288um_0um_merge           19.9   21.5   45.3   62.0   75.5   72.3   57.2   23.3   18.2    0.0
20170504_396um_0um_merge           34.8   28.0   40.4   55.3   70.2   70.8   61.5   36.4   26.3    0.5
20170505_396um_0um_merge           32.5   37.4   50.6   59.2   64.1   60.9   55.6   43.4   33.1    0.0
20170506_468um_36um_170506_11183   33.7   39.0   52.8   62.3   67.5   63.9   57.6   43.8   31.9    0.0
20170507_468um_36um_merge          28.9   24.8   51.4   72.4   87.4   80.0   57.7   19.7   28.1    0.0
20170509_468um_36um_170509_10345   25.3   36.0   49.7   58.8   63.6   58.6   51.2   38.1   23.6    0.0
20170518_828um_864um_merge         30.6   37.9   53.3   63.7   70.6   66.8   59.8   43.7   30.2    0.0
20170519_864um_900um_merge         22.7   35.6   50.7   62.8   70.9   65.9   57.4   40.4   20.1    0.0
20170521_900um_936um_170521_1256   34.5   19.8   47.1   70.4   87.4   84.0   59.5   17.1   27.3    0.0
20170522_900um_936um_170522_1511   32.5   24.0   46.3   65.5   79.5   76.3   61.7   26.4   24.8    0.0
20170525_900um_936um_170525_1501   24.1   22.9   51.2   70.2   82.6   75.7   57.0   21.0   20.7    0.0

Peak lag of speed inside trials, files per lag: {-2.0: 1, 0.0: 59, 0.5: 6, 1.0: 1}
Speed at lag 0 over speed at +-3 s, median 2.22 | range 1.03 to 4.45

Theta phase locking (mean resultant length) of hippocampal spikes, LFP shifted by each lag (ms):
                                   -200   -175   -150   -125   -100    -75    -50    -25      0     25     50     75    100    125    150    175    200  peak
name                                                                                                                                                         
DT2_rPPC_rCCG_3324um_1144um_2016  0.139  0.145  0.151  0.157  0.162  0.167  0.170  0.173  0.175  0.176  0.175  0.174  0.172  0.169  0.164  0.159  0.153    25
DT2_rPPC_rCCG_3396um_1180um_2016  0.129  0.136  0.142  0.148  0.155  0.161  0.165  0.168  0.170  0.172  0.172  0.170  0.166  0.163  0.159  0.154  0.147    25
DT2_rPPC_rCCG_3396um_1180um_2016  0.140  0.145  0.150  0.156  0.160  0.164  0.168  0.171  0.173  0.173  0.173  0.172  0.170  0.167  0.164  0.159  0.155    25
DT2_rPPC_rCCG_3468um_1216um_2016  0.120  0.125  0.130  0.134  0.138  0.142  0.145  0.148  0.149  0.150  0.151  0.150  0.148  0.145  0.142  0.139  0.135    50
DT2_rPPC_rCCG_3468um_1216um_2016  0.173  0.180  0.186  0.193  0.198  0.203  0.208  0.212  0.214  0.216  0.216  0.215  0.213  0.210  0.207  0.202  0.197    50
DT2_rPPC_rCCG_3468um_1216um_2016  0.080  0.088  0.096  0.103  0.112  0.120  0.127  0.132  0.136  0.137  0.136  0.134  0.130  0.124  0.117  0.109  0.100    25
DT2_rPPC_rCCG_3468um_1252um_2016  0.151  0.157  0.161  0.165  0.169  0.173  0.176  0.178  0.179  0.180  0.181  0.180  0.178  0.176  0.173  0.170  0.166    50
DT2_rPPC_rCCG_3540um_1288um_2016  0.135  0.139  0.143  0.147  0.151  0.154  0.157  0.159  0.160  0.161  0.161  0.159  0.158  0.155  0.153  0.149  0.145    25
DT2_rPPC_rCCG_3540um_1288um_2016  0.161  0.167  0.172  0.177  0.182  0.187  0.191  0.194  0.196  0.197  0.198  0.197  0.194  0.191  0.188  0.184  0.179    50
DT2_rPPC_rCCG_3612um_1360um_2016  0.244  0.254  0.263  0.273  0.283  0.292  0.301  0.308  0.313  0.317  0.317  0.314  0.310  0.305  0.298  0.290  0.279    25
20161011_972um_1224um_merge       0.244  0.257  0.273  0.283  0.293  0.301  0.310  0.316  0.320  0.320  0.319  0.315  0.308  0.300  0.290  0.277  0.263    25
20161014_1296um_1476um_merge      0.039  0.046  0.053  0.057  0.062  0.069  0.076  0.079  0.080  0.080  0.080  0.080  0.075  0.070  0.068  0.067  0.063    50
20161015_1368um_1476um_merge      0.091  0.097  0.103  0.109  0.114  0.122  0.129  0.135  0.139  0.143  0.142  0.139  0.135  0.132  0.127  0.122  0.113    25
20161016_1368um_1476um_merge      0.100  0.109  0.120  0.128  0.129  0.132  0.138  0.145  0.146  0.140  0.140  0.142  0.136  0.125  0.120  0.114  0.110     0
20161018_1552um_2304um_merge      0.086  0.093  0.101  0.109  0.115  0.119  0.122  0.124  0.123  0.120  0.113  0.106  0.098  0.088  0.077  0.068  0.063   -25
20161019_1624um_2340um_161019_09  0.087  0.098  0.110  0.119  0.123  0.127  0.130  0.133  0.129  0.121  0.113  0.102  0.090  0.075  0.066  0.062  0.061   -25
20161020_1768um_2376um_161020_10  0.080  0.088  0.096  0.104  0.109  0.112  0.114  0.113  0.110  0.105  0.099  0.091  0.084  0.076  0.069  0.062  0.057   -50
20161021_1840um_2412um_merge      0.174  0.188  0.205  0.218  0.225  0.234  0.245  0.252  0.250  0.243  0.236  0.231  0.222  0.207  0.191  0.180  0.172   -25
20161023_1872um_2448um_161023_12  0.075  0.076  0.079  0.086  0.089  0.088  0.086  0.087  0.089  0.089  0.088  0.090  0.091  0.091  0.089  0.085  0.082   125
20161025_1944um_2232um_merge      0.105  0.112  0.118  0.124  0.131  0.135  0.139  0.143  0.144  0.143  0.140  0.134  0.126  0.120  0.114  0.108  0.101     0
20161026_1944um_2232um_merge      0.054  0.056  0.063  0.067  0.065  0.061  0.059  0.064  0.064  0.060  0.056  0.058  0.059  0.052  0.043  0.039  0.040  -125
20161027_1944um_2232um_161027_19  0.039  0.043  0.052  0.057  0.058  0.059  0.061  0.063  0.059  0.056  0.056  0.056  0.055  0.047  0.040  0.038  0.038   -25
20161030_2052um_2232um_161030_11  0.101  0.105  0.109  0.114  0.119  0.122  0.123  0.123  0.120  0.114  0.106  0.098  0.093  0.088  0.083  0.077  0.075   -50
20161031_2088um_2232um_161031_10  0.012  0.014  0.016  0.020  0.022  0.025  0.026  0.028  0.028  0.028  0.026  0.022  0.017  0.014  0.011  0.006  0.003     0
20161101_2088um_2232um_merge      0.058  0.062  0.067  0.073  0.077  0.079  0.079  0.078  0.076  0.072  0.068  0.063  0.058  0.053  0.045  0.039  0.032   -75
20161104_2124um_2232um_merge      0.095  0.100  0.106  0.111  0.115  0.118  0.120  0.120  0.118  0.112  0.105  0.098  0.092  0.087  0.081  0.077  0.073   -50
20170315_288um_0um_170315_191240  0.126  0.131  0.135  0.139  0.143  0.147  0.149  0.151  0.153  0.153  0.152  0.152  0.150  0.147  0.143  0.140  0.137    25
20170318_288um_0um_170318_115923  0.210  0.217  0.223  0.228  0.233  0.238  0.241  0.244  0.247  0.247  0.245  0.243  0.241  0.237  0.233  0.228  0.222    25
20170320_432um_0um_merge          0.122  0.126  0.130  0.134  0.137  0.139  0.142  0.145  0.146  0.145  0.144  0.144  0.144  0.141  0.137  0.134  0.132     0
20170321_216um_0um_170321_120259  0.129  0.134  0.138  0.142  0.145  0.148  0.151  0.153  0.153  0.153  0.153  0.153  0.151  0.148  0.145  0.142  0.139     0
20170325_576um_360um_170325_1255  0.050  0.051  0.053  0.056  0.059  0.061  0.062  0.064  0.065  0.066  0.066  0.066  0.067  0.066  0.063  0.061  0.061   100
20170401_864um_936um_merge        0.073  0.079  0.084  0.091  0.098  0.104  0.108  0.111  0.114  0.113  0.110  0.106  0.100  0.098  0.096  0.091  0.085     0
20170412_1440um_1170um_170412_10  0.116  0.118  0.120  0.121  0.121  0.123  0.124  0.124  0.122  0.118  0.116  0.116  0.114  0.109  0.105  0.103  0.103   -25
20170429_0um_0um_merge            0.127  0.133  0.138  0.144  0.149  0.153  0.156  0.160  0.162  0.164  0.164  0.163  0.162  0.159  0.155  0.151  0.146    50
20170430_0um_0um_merge            0.175  0.179  0.183  0.186  0.189  0.192  0.195  0.196  0.197  0.198  0.198  0.196  0.193  0.190  0.187  0.183  0.179    25
20170501_216um_0um_170501_112210  0.184  0.191  0.197  0.203  0.208  0.213  0.216  0.218  0.219  0.219  0.218  0.215  0.210  0.205  0.199  0.192  0.184     0
20170502_288um_0um_merge          0.185  0.193  0.200  0.207  0.212  0.216  0.220  0.222  0.222  0.220  0.218  0.214  0.209  0.202  0.194  0.187  0.179   -25
20170504_396um_0um_merge          0.130  0.137  0.143  0.148  0.153  0.158  0.162  0.165  0.165  0.166  0.166  0.165  0.162  0.159  0.156  0.154  0.151    50
20170505_396um_0um_merge          0.126  0.132  0.137  0.142  0.147  0.153  0.158  0.162  0.165  0.168  0.169  0.170  0.169  0.167  0.164  0.160  0.156    75
20170506_468um_36um_170506_11183  0.151  0.155  0.160  0.165  0.170  0.175  0.179  0.183  0.186  0.189  0.190  0.190  0.189  0.187  0.184  0.180  0.176    75
20170507_468um_36um_merge         0.157  0.161  0.165  0.167  0.170  0.172  0.174  0.174  0.172  0.169  0.166  0.162  0.156  0.148  0.141  0.134  0.127   -50
20170509_468um_36um_170509_10345  0.208  0.216  0.223  0.229  0.234  0.239  0.243  0.246  0.248  0.248  0.248  0.246  0.243  0.239  0.234  0.229  0.224     0
20170518_828um_864um_merge        0.184  0.190  0.198  0.205  0.212  0.219  0.223  0.225  0.225  0.224  0.220  0.215  0.208  0.201  0.195  0.187  0.180     0
20170519_864um_900um_merge        0.118  0.123  0.125  0.126  0.125  0.126  0.128  0.130  0.129  0.129  0.132  0.131  0.130  0.129  0.127  0.127  0.127    50
20170521_900um_936um_170521_1256  0.171  0.178  0.182  0.184  0.186  0.190  0.192  0.195  0.196  0.193  0.190  0.187  0.184  0.179  0.172  0.164  0.157     0
20170522_900um_936um_170522_1511  0.166  0.173  0.179  0.183  0.185  0.190  0.194  0.197  0.196  0.194  0.193  0.196  0.196  0.191  0.187  0.185  0.183   -25
20170525_900um_936um_170525_1501  0.155  0.162  0.166  0.166  0.168  0.171  0.171  0.171  0.170  0.171  0.171  0.171  0.168  0.165  0.164  0.162  0.158    50
Files per peak lag (ms): {-125: 1, -75: 1, -50: 4, -25: 7, 0: 10, 25: 11, 50: 9, 75: 2, 100: 1, 125: 1}
Locking at 0 ms over locking at +-200 ms, median 1.2

Mean firing rate of all units in the trial windows shifted by each lag, files per peak lag: {-3.0: 2, -2.0: 5, -1.0: 7, 0.0: 16, 0.5: 14, 1.0: 4, 2.0: 10, 3.0: 8}

Three clock checks, each a contrast between the true and shifted alignments.

  • Positions against the trials table: running speed inside the trial windows peaks at a lag of 0 or 0.5 s in 65 of 67 files and is a median 2.2 times its value at 3 s, so positions and trials share a clock to within about half a second. In DT9 20170501 speed does not change with the lag (31.5 cm/s at 0 against 29.1 to 32.8 at other lags): its trials do not match its positions, and it is left out by the condition rule (no condition reaches 10 trials). In one DT2 file (20160221) speed peaks at a lag of 1 s; its trials may be offset from its positions by up to a second. This is consistent with the data, not proven for every trial.
  • Spikes against the LFP: theta phase locking of hippocampal spikes peaks within 75 ms of zero lag in 44 of the 47 files with hippocampal units and a theta channel, and at 200 ms it is lower by a median of about a sixth (ratio 1.2). The contrast is weak: theta has a period of about 125 ms, so a shift of 200 ms is under two cycles. This is consistent with a shared clock to within about 100 ms, and does not prove it. It could not be checked in the 17 DT8 files and the three DT2 and DT7 files without labelled hippocampal units.
  • Spikes against the trials: the mean rate of all units in the trial windows changes little with the lag (running modulates many LS units weakly or negatively), so this contrast does not settle the alignment of spikes and trials. It is not established for the LS-only sessions beyond the spike-LFP check of the other files.
In [8]:
print("processing/behavior/allocentric_frame_tracking, per subject:")
for subj, g in S.groupby("subject"):
    held = [d for d in g.allocentric_frame_tracking if d]
    print(f"  {subj}: in {len(held)} of {len(g)} files;", held[0] if held else "")
processing/behavior/allocentric_frame_tracking, per subject:
  DT2: in 0 of 11 files; 
  DT5: in 16 of 16 files; {'orientation/data': ((512745, 4), 'meters'), 'orientation/reference_frame': ((), ''), 'orientation/timestamps': ((512745,), 'seconds'), 'orientation description': '(x, y, z, w) orientation coordinates, orientation type: quaternion'}
  DT7: in 9 of 9 files; {'orientation/data': ((257372, 4), 'meters'), 'orientation/reference_frame': ((), ''), 'orientation/timestamps': ((257372,), 'seconds'), 'orientation description': '(x, y, z, w) orientation coordinates, orientation type: quaternion'}
  DT8: in 17 of 17 files; {'orientation/data': ((249460, 4), 'meters'), 'orientation/reference_frame': ((), ''), 'orientation/timestamps': ((249460,), 'seconds'), 'orientation description': '(x, y, z, w) orientation coordinates, orientation type: quaternion'}
  DT9: in 14 of 14 files; {'orientation/data': ((301541, 4), 'meters'), 'orientation/reference_frame': ((), ''), 'orientation/timestamps': ((301541,), 'seconds'), 'orientation description': '(x, y, z, w) orientation coordinates, orientation type: quaternion'}

processing/behavior/allocentric_frame_tracking holds one series, orientation: a head-orientation quaternion (x, y, z, w) with its timestamps, in every file of DT5, DT7, DT8 and DT9 and in none of DT2. Its stated unit is metres, which does not apply to a quaternion. Nothing in it, or in the trials table, marks a maze rotation, so figs6-reference-frame stays blocked.

LS neurons recorded (ls-neuron-count)¶

A total of 1,647 LS neurons were recorded from five animals, in 62 sessions.

In [9]:
ls_units = units["ls"]
print("LS units per subject:", ls_units.drop("all").to_dict(), "| total", int(ls_units["all"]))
n_ls_sessions = sum("ls" in d for d in S.unit_locations)
print("Sessions with LS units:", n_ls_sessions, "| subjects with LS units:", int((ls_units.drop("all") > 0).sum()))
print("Paper: 1,647 LS neurons, 62 sessions, five animals. Difference in units:",
      int(ls_units["all"]) - 1647, f"({(int(ls_units['all']) - 1647) / 1647:+.1%})")
print("Unlabelled units (DT7 20170317), not counted:", int(units.loc["all"].get("unlabelled", 0)))
LS units per subject: {'DT2': 375, 'DT5': 480, 'DT7': 60, 'DT8': 296, 'DT9': 485} | total 1696
Sessions with LS units: 62 | subjects with LS units: 5
Paper: 1,647 LS neurons, 62 sessions, five animals. Difference in units: 49 (+3.0%)
Unlabelled units (DT7 20170317), not counted: 43

Result: reproduced. 1,696 units are labelled LS, 3.0% more than the paper's 1,647 and within tolerance, in 62 sessions as in the paper, and all five rats hold LS units.

Hippocampal units (hpc-unit-count)¶

The hippocampal recordings hold 2,297 isolated CA1 units and 654 CA3 units (2,951 in all).

In [10]:
ca1, ca3 = int(units.loc["all", "hpc"]), int(units.loc["all", "ca3"])
print("Units labelled hpc (taken as CA1) per subject:", units["hpc"].drop("all").to_dict(), "| total", ca1)
print("Units labelled ca3 per subject:", units["ca3"].drop("all").to_dict(), "| total", ca3)
print(f"CA1: {ca1} against 2,297 ({(ca1 - 2297) / 2297:+.1%}); CA3: {ca3} against 654 ({(ca3 - 654) / 654:+.1%}); "
      f"sum {ca1 + ca3} against 2,951 ({(ca1 + ca3 - 2951) / 2951:+.1%})")
print("Sessions with hpc units:", int(S.has_hpc_units.sum()) - int(S.has_ca3_units.sum()), "| with ca3 units:", int(S.has_ca3_units.sum()),
      "| paper, Figure 6A: 63 CA1 and 19 CA3 sessions; 45 hippocampal sessions in Figure 1I")
Units labelled hpc (taken as CA1) per subject: {'DT2': 1035, 'DT5': 329, 'DT7': 446, 'DT8': 0, 'DT9': 783} | total 2593
Units labelled ca3 per subject: {'DT2': 0, 'DT5': 279, 'DT7': 0, 'DT8': 0, 'DT9': 345} | total 624
CA1: 2593 against 2,297 (+12.9%); CA3: 624 against 654 (-4.6%); sum 3217 against 2,951 (+9.0%)
Sessions with hpc units: 36 | with ca3 units: 11 | paper, Figure 6A: 63 CA1 and 19 CA3 sessions; 45 hippocampal sessions in Figure 1I

Result: partially reproduced. 2,593 units are labelled hpc against 2,297 CA1 units (+12.9%, outside tolerance) and 624 are labelled ca3 against 654 (-4.6%, within). Their sum, 3,217, is 9.0% above 2,951. The labels hpc and ca3 are read as CA1 and CA3; the dandiset does not say that hpc means CA1.

LS neurons passing the activity criterion (ls-active-neurons)¶

Of the LS neurons, 840 fired at least 1.5 action potentials per trial on average.

In [11]:
ls_all = C[C.region == "ls"]
def active_neurons(df, k):
    return df[df.n_spikes >= k * df.n_trials].groupby("neuron").ngroups
n_active = LS.neuron.nunique()
print("LS units in a condition with at least 10 trials:", ls_all.neuron.nunique(), "of", int(units.loc["all", "ls"]))
print("Active LS neurons (1.5 spikes per trial in at least one condition):", n_active, "| paper 840")
print("Per subject:", LS.groupby("subject").neuron.nunique().to_dict())
print("Included LS conditions (neuron and condition pairs):", len(LS), "| paper 4,393 conditions")
for k in (1.0, 1.5, 2.0, 3.0):
    print(f"  threshold {k} spikes per trial: {active_neurons(ls_all, k)} neurons")
LS units in a condition with at least 10 trials: 1630 of 1696
Active LS neurons (1.5 spikes per trial in at least one condition): 793 | paper 840
Per subject: {'DT2': 174, 'DT5': 309, 'DT7': 18, 'DT8': 131, 'DT9': 161}
Included LS conditions (neuron and condition pairs): 3694 | paper 4,393 conditions
  threshold 1.0 spikes per trial: 932 neurons
  threshold 1.5 spikes per trial: 793 neurons
  threshold 2.0 spikes per trial: 707 neurons
  threshold 3.0 spikes per trial: 563 neurons

Result: reproduced. 793 LS neurons fire at least 1.5 spikes per trial in a condition with at least 10 trials, against 840 (-5.6%, within tolerance), over 3,694 neuron-condition pairs (the paper has 4,393). The count depends on how conditions are formed, which the dandiset does not record.

Phase coding against shuffled data (fig2-ls-phase-vs-shuffle)¶

The majority of LS neurons (751 of 840, 89%) showed position encoding in their spike theta phase, compared with shuffled data, in at least one condition.

In [12]:
def frac_neurons(df, mask):
    return mask.groupby(df.neuron).any()

sig_chance = (LSd.p_phase_vs_chance < 0.01) & (LSd.mse_phase < LSd.mse_chance_phase)
per_neuron = frac_neurons(LSd, sig_chance)
print(f"Active LS neurons decoded: {LSd.neuron.nunique()} (dropped {n_active - LSd.neuron.nunique()} in the file without theta reference)")
print(f"Neurons with phase MSE below chance at p < 0.01 in at least one condition: {int(per_neuron.sum())} "
      f"of {len(per_neuron)} = {per_neuron.mean():.3f} | paper 751 of 840 = 0.894")
print("Conditions significant:", f"{sig_chance.mean():.3f}", "of", len(LSd))
print("Per subject:", per_neuron.groupby([S.subject[n[0]] for n in per_neuron.index]).mean().round(3).to_dict())
for p in (0.05, 0.01, 0.001):
    m = (LSd.p_phase_vs_chance < p) & (LSd.mse_phase < LSd.mse_chance_phase)
    print(f"  p < {p}: {frac_neurons(LSd, m).mean():.3f} of neurons")
print("Mean MSE (bins^2) over LS conditions: phase", round(LSd.mse_phase.mean()), "| chance phase", round(LSd.mse_chance_phase.mean()),
      "| rate", round(LSd.mse_rate.mean()), "| chance rate", round(LSd.mse_chance_rate.mean()),
      "| uniform guessing over 200 bins", round(2 * (200**2 - 1) / 12))
rate_sig = (LSd.p_rate_vs_chance < 0.01) & (LSd.mse_rate < LSd.mse_chance_rate)
print(f"For comparison, rate MSE below chance at p < 0.01: {frac_neurons(LSd, rate_sig).mean():.3f} of neurons")
good_theta = S.session[S.theta_ratio > 1]
m1 = LSd.session.isin(good_theta)
pn = frac_neurons(LSd[m1], sig_chance[m1])
print(f"Variant, sessions whose theta channel has more 6-9 Hz than 1-4 Hz power ({LSd[m1].session.nunique()} sessions): "
      f"{pn.mean():.3f} of {len(pn)} neurons; other sessions: {frac_neurons(LSd[~m1], sig_chance[~m1]).mean():.3f}")
Active LS neurons decoded: 783 (dropped 10 in the file without theta reference)
Neurons with phase MSE below chance at p < 0.01 in at least one condition: 408 of 783 = 0.521 | paper 751 of 840 = 0.894
Conditions significant: 0.232 of 3660
Per subject: {'DT2': 0.39, 'DT5': 0.56, 'DT7': 0.556, 'DT8': 0.458, 'DT9': 0.627}
  p < 0.05: 0.660 of neurons
  p < 0.01: 0.521 of neurons
  p < 0.001: 0.433 of neurons
Mean MSE (bins^2) over LS conditions: phase 6359 | chance phase 6839 | rate 7404 | chance rate 7996 | uniform guessing over 200 bins 6666
For comparison, rate MSE below chance at p < 0.01: 0.544 of neurons
Variant, sessions whose theta channel has more 6-9 Hz than 1-4 Hz power (37 sessions): 0.529 of 456 neurons; other sessions: 0.511

Result: not reproduced. 52.1% of the decoded active LS neurons (408 of 783) decode position from phase better than chance at p < 0.01 in at least one condition, against 89% in the paper. With p < 0.05 the fraction is 66.0%, still outside tolerance; at p < 0.01 the rate code passes the same test against its own chance in 54.4% of neurons. In the 37 sessions whose theta channel has more 6 to 9 Hz than 1 to 4 Hz power the fraction is 52.9%, so a weak theta reference does not account for the gap. The decoder and the phase maps are rebuilt from the Methods and code, without the paper's linearization, conditions or theta channel.

Phase decoding better than rate decoding (fig2-ls-phase-beats-rate)¶

Spike-phase decoding outperformed rate decoding of the rat's position for 786 of 840 LS neurons, 3,046 of 4,393 conditions, and 62 of 62 sessions.

In [13]:
better = (LSd.p_phase_vs_rate < 0.01) & (LSd.mse_phase < LSd.mse_rate)
nb = frac_neurons(LSd, better)
ses = LSd.groupby("session")[["mse_phase", "mse_rate"]].mean()
print(f"Neurons: {int(nb.sum())} of {len(nb)} = {nb.mean():.3f} | paper 786 of 840 = 0.936")
print(f"Conditions: {int(better.sum())} of {len(better)} = {better.mean():.3f} | paper 3,046 of 4,393 = 0.693")
print(f"Sessions with lower mean phase than rate MSE: {int((ses.mse_phase < ses.mse_rate).sum())} of {len(ses)} = "
      f"{(ses.mse_phase < ses.mse_rate).mean():.3f} | paper 62 of 62")
worse = (LSd.p_phase_vs_rate < 0.01) & (LSd.mse_phase > LSd.mse_rate)
print(f"Conditions where rate is better at p < 0.01: {worse.mean():.3f}")
by = pd.DataFrame({"neurons": nb.groupby([S.subject[n[0]] for n in nb.index]).mean(),
                   "conditions": better.groupby(LSd.subject).mean(),
                   "sessions": (ses.mse_phase < ses.mse_rate).groupby(S.subject[ses.index].values).mean()})
print("\nPer subject (fractions):")
print(by.round(3).to_string())
for p in (0.05, 0.001):
    m = (LSd.p_phase_vs_rate < p) & (LSd.mse_phase < LSd.mse_rate)
    print(f"  p < {p}: neurons {frac_neurons(LSd, m).mean():.3f}, conditions {m.mean():.3f}")
bt = (LSd.p_phase_vs_rate_trialsplit < 0.01) & (LSd.mse_phase_trialsplit < LSd.mse_rate_trialsplit)
print(f"Variant, whole trials held out: neurons {frac_neurons(LSd, bt).mean():.3f}, conditions {bt.mean():.3f}")
nb1 = frac_neurons(LSd[m1], better[m1])
print(f"Variant, sessions with theta ratio above 1: neurons {nb1.mean():.3f} of {len(nb1)}, conditions {better[m1].mean():.3f} of {int(m1.sum())}")
Neurons: 662 of 783 = 0.845 | paper 786 of 840 = 0.936
Conditions: 1762 of 3660 = 0.481 | paper 3,046 of 4,393 = 0.693
Sessions with lower mean phase than rate MSE: 58 of 58 = 1.000 | paper 62 of 62
Conditions where rate is better at p < 0.01: 0.053
Per subject (fractions):
     neurons  conditions  sessions
DT2    0.945       0.630       1.0
DT5    0.793       0.412       1.0
DT7    0.722       0.290       1.0
DT8    0.824       0.486       1.0
DT9    0.876       0.477       1.0
  p < 0.05: neurons 0.895, conditions 0.601
  p < 0.001: neurons 0.714, conditions 0.328
Variant, whole trials held out: neurons 0.729, conditions 0.354
Variant, sessions with theta ratio above 1: neurons 0.875 of 456, conditions 0.528 of 2029

Result: not reproduced. Phase beats rate at p < 0.01 in 84.5% of neurons (paper 93.6%) and 48.1% of conditions (paper 69.3%), both outside tolerance, and in 58 of 58 sessions (paper 62 of 62). As fewer than half the conditions pass, the criterion's partial outcome does not apply. The direction holds in every rat and session. In the 37 sessions with a theta ratio above 1, 87.5% of neurons and 52.8% of conditions pass. Samples, not whole trials, are split at random, as the paper's per-cell decoder does (randperm over all trial-by-bin samples in scratch_07_11_17_spatialBinnedMaxCorr.m); with whole trials held out the fractions fall to 72.9% and 35.4%.

Phase MSE lower than rate MSE (fig2e-ls-phase-lower-mse)¶

Across LS neurons the spike-phase code is stronger than the rate code (two-sample t tests; N = 4,393 conditions, p < 1e-100; N = 62 sessions, p < 1e-10).

In [14]:
t_c = stats.ttest_ind(LSd.mse_phase, LSd.mse_rate)
t_s = stats.ttest_ind(ses.mse_phase, ses.mse_rate)
print(f"Conditions (N = {len(LSd)}): phase {LSd.mse_phase.mean():.0f}, rate {LSd.mse_rate.mean():.0f}; t = {t_c.statistic:.1f}, p = {t_c.pvalue:.2e}")
print(f"Sessions (N = {len(ses)}): phase {ses.mse_phase.mean():.0f}, rate {ses.mse_rate.mean():.0f}; t = {t_s.statistic:.1f}, p = {t_s.pvalue:.2e}")
print("Per subject, conditions:")
for subj, g in LSd.groupby("subject"):
    t = stats.ttest_ind(g.mse_phase, g.mse_rate)
    print(f"  {subj}: N = {len(g)}, phase {g.mse_phase.mean():.0f}, rate {g.mse_rate.mean():.0f}, p = {t.pvalue:.1e}")
tg = stats.ttest_ind(LSd[m1].mse_phase, LSd[m1].mse_rate)
print(f"Variant, sessions with theta ratio above 1: phase {LSd[m1].mse_phase.mean():.0f}, rate {LSd[m1].mse_rate.mean():.0f}, p = {tg.pvalue:.1e}")
tt = stats.ttest_ind(LSd.mse_phase_trialsplit, LSd.mse_rate_trialsplit)
print(f"Variant, whole trials held out: phase {LSd.mse_phase_trialsplit.mean():.0f}, rate {LSd.mse_rate_trialsplit.mean():.0f}, p = {tt.pvalue:.1e}")
fig, ax = plt.subplots(1, 2, figsize=(10, 3.5))
bins = np.arange(2000, 14001, 250)
ax[0].hist(LSd.mse_phase, bins, alpha=.6, label="phase"); ax[0].hist(LSd.mse_rate, bins, alpha=.6, label="rate")
ax[0].set_xlabel("MSE (bins$^2$)"); ax[0].set_ylabel("LS conditions"); ax[0].legend()
d = LSd.mse_phase - LSd.mse_rate
ax[1].hist(d, np.arange(-6000, 6001, 200), color="m"); ax[1].set_xlabel("MSE phase - rate (bins$^2$)")
plt.tight_layout(); plt.show()
print("Outside the axes: MSE", int(((LSd.mse_phase < 2000) | (LSd.mse_phase > 14000)).sum()), "phase and",
      int(((LSd.mse_rate < 2000) | (LSd.mse_rate > 14000)).sum()), "rate values; difference", int((d.abs() > 6000).sum()),
      "| ranges: phase", LSd.mse_phase.min().round(), "to", LSd.mse_phase.max().round(), ", rate", LSd.mse_rate.min().round(), "to", LSd.mse_rate.max().round())
Conditions (N = 3660): phase 6359, rate 7404; t = -33.8, p = 2.49e-232
Sessions (N = 58): phase 6349, rate 7481; t = -12.6, p = 2.85e-23
Per subject, conditions:
  DT2: N = 787, phase 6407, rate 7835, p = 9.5e-92
  DT5: N = 1501, phase 6492, rate 7364, p = 3.1e-68
  DT7: N = 69, phase 6381, rate 6946, p = 1.8e-02
  DT8: N = 551, phase 6202, rate 7368, p = 2.4e-55
  DT9: N = 752, phase 6156, rate 7103, p = 2.1e-39
Variant, sessions with theta ratio above 1: phase 6275, rate 7402, p = 2.9e-147
Variant, whole trials held out: phase 6527, rate 7920, p = 0.0e+00
No description has been provided for this image
Outside the axes: MSE 0 phase and 0 rate values; difference 8 | ranges: phase 3438.0 to 10826.0 , rate 2022.0 to 13214.0

Result: reproduced. Over 3,660 LS conditions the phase MSE (6,359) is below the rate MSE (7,404), t = -33.8, p = 2.5e-232, below the paper's 1e-100; over 58 sessions p = 2.9e-23, below 1e-10. It holds in each rat (DT7 only at p = 0.018), in the sessions with a theta ratio above 1 (p = 2.9e-147) and with whole trials held out.

Hippocampal place fields, rate and phase decoding (fig1i-hpc-rate-phase-equivalent)¶

For hippocampal place fields the distributions of rate and phase decoding errors are statistically equivalent (two-sample KS test; 1,820 place fields, p = 0.19; 45 sessions, p = 0.61).

In [15]:
PF = HPd[HPd.n_fields > 0]
hs = PF.groupby("session")[["mse_phase", "mse_rate"]].mean()
k1 = stats.ks_2samp(PF.mse_phase, PF.mse_rate)
k2 = stats.ks_2samp(hs.mse_phase, hs.mse_rate)
print(f"Place fields: N = {len(PF)} (paper 1,820); phase {PF.mse_phase.mean():.0f}, rate {PF.mse_rate.mean():.0f}; "
      f"KS D = {k1.statistic:.3f}, p = {k1.pvalue:.3f}; mean difference {(PF.mse_phase - PF.mse_rate).mean():.0f}")
print(f"Sessions: N = {len(hs)} (paper 45); KS D = {k2.statistic:.3f}, p = {k2.pvalue:.3f}; mean difference {(hs.mse_phase - hs.mse_rate).mean():.0f}")
print("Per subject (fields):")
for subj, g in PF.groupby("subject"):
    k = stats.ks_2samp(g.mse_phase, g.mse_rate)
    print(f"  {subj}: N = {len(g)}, phase - rate {(g.mse_phase - g.mse_rate).mean():.0f}, KS p = {k.pvalue:.3f}")
k3 = stats.ks_2samp(HPd.mse_phase, HPd.mse_rate)
print(f"Variant, all included hippocampal conditions (N = {len(HPd)}): phase - rate {(HPd.mse_phase - HPd.mse_rate).mean():.0f}, KS p = {k3.pvalue:.2e}")
k4 = stats.ks_2samp(PF.mse_phase_trialsplit, PF.mse_rate_trialsplit)
print(f"Variant, whole trials held out: phase - rate {(PF.mse_phase_trialsplit - PF.mse_rate_trialsplit).mean():.0f}, KS p = {k4.pvalue:.3f}")
PFb = HPd[HPd.n_fields_box5 > 0]
k5 = stats.ks_2samp(PFb.mse_phase, PFb.mse_rate)
print(f"Variant, fields of the 5-bin box map: N = {len(PFb)}, phase - rate {(PFb.mse_phase - PFb.mse_rate).mean():.0f}, KS p = {k5.pvalue:.3f}")
PFn = HPd[HPd.n_fields_nosd > 0]
k6 = stats.ks_2samp(PFn.mse_phase, PFn.mse_rate)
print(f"Variant, fields without the rule dropping peaks whose SD across trials exceeds their mean: N = {len(PFn)}, "
      f"phase - rate {(PFn.mse_phase - PFn.mse_rate).mean():.0f}, KS D = {k6.statistic:.3f}, p = {k6.pvalue:.3f}")
Place fields: N = 531 (paper 1,820); phase 5846, rate 6081; KS D = 0.085, p = 0.044; mean difference -234
Sessions: N = 42 (paper 45); KS D = 0.167, p = 0.610; mean difference -126
Per subject (fields):
  DT2: N = 230, phase - rate -365, KS p = 0.001
  DT5: N = 94, phase - rate -104, KS p = 0.785
  DT7: N = 41, phase - rate -118, KS p = 0.779
  DT9: N = 166, phase - rate -155, KS p = 0.508
Variant, all included hippocampal conditions (N = 5045): phase - rate -419, KS p = 7.36e-48
Variant, whole trials held out: phase - rate -448, KS p = 0.000
Variant, fields of the 5-bin box map: N = 318, phase - rate -172, KS p = 0.097
Variant, fields without the rule dropping peaks whose SD across trials exceeds their mean: N = 2320, phase - rate -282, KS D = 0.104, p = 0.000

Result: not reproduced. Over 531 hippocampal place fields the KS test finds a difference between phase and rate MSE (D = 0.085, p = 0.044), where the paper finds none (p = 0.19); over 42 sessions it finds none (p = 0.61). The phase MSE is lower by 234 bins squared on average over fields. The result sits near the threshold and depends on the set of fields: with the 318 fields of the 5-bin box map p = 0.097, and per rat only DT2 differs (p = 0.001). Without the code's rule dropping peaks whose SD across trials exceeds their mean, 2,320 fields are found, more than the paper's 1,820, and the distributions differ more clearly (D = 0.104, p below 0.001). Only 531 fields are found here, against 1,820 (see ls-few-place-fields); over all hippocampal conditions the distributions differ (p = 7.4e-48).

Mean phase minus rate MSE (fig2fg-mse-difference)¶

The mean phase minus rate MSE is about -1,000 for LS conditions and -33 for hippocampal place fields, and -1,024 and -25 for LS and hippocampal sessions.

In [16]:
vals = {"LS conditions": (LSd.mse_phase - LSd.mse_rate).mean(), "hippocampal place fields": (PF.mse_phase - PF.mse_rate).mean(),
        "LS sessions": (ses.mse_phase - ses.mse_rate).mean(), "hippocampal sessions": (hs.mse_phase - hs.mse_rate).mean()}
paper = {"LS conditions": -1000, "hippocampal place fields": -33, "LS sessions": -1024, "hippocampal sessions": -25}
for k, v in vals.items():
    print(f"{k}: {v:.0f} (paper {paper[k]}, tolerance +-{abs(paper[k]) * 0.1:.1f})")
print("\nPer subject, LS conditions and hippocampal place fields:")
print(pd.DataFrame({"LS": (LSd.mse_phase - LSd.mse_rate).groupby(LSd.subject).mean(),
                    "HPC fields": (PF.mse_phase - PF.mse_rate).groupby(PF.subject).mean()}).round(0).to_string())
print("\nVariant, whole trials held out: LS", round((LSd.mse_phase_trialsplit - LSd.mse_rate_trialsplit).mean()),
      "| hippocampal fields", round((PF.mse_phase_trialsplit - PF.mse_rate_trialsplit).mean()))
LS conditions: -1045 (paper -1000, tolerance +-100.0)
hippocampal place fields: -234 (paper -33, tolerance +-3.3)
LS sessions: -1132 (paper -1024, tolerance +-102.4)
hippocampal sessions: -126 (paper -25, tolerance +-2.5)

Per subject, LS conditions and hippocampal place fields:
             LS  HPC fields
subject                    
DT2     -1428.0      -365.0
DT5      -872.0      -104.0
DT7      -565.0      -118.0
DT8     -1165.0         NaN
DT9      -947.0      -155.0

Variant, whole trials held out: LS -1393 | hippocampal fields -448

Result: partially reproduced. The LS condition mean, -1,045, is within tolerance of -1,000; the LS session mean, -1,132, is just outside -1,024 +- 102; the hippocampal values, -234 for place fields and -126 for sessions, are far from -33 and -25. LS values are negative and larger in magnitude than the hippocampal ones at both levels.

Place fields in LS and hippocampus (ls-few-place-fields)¶

Only 5.3% (232 of 4,393) of LS rate maps showed place fields by the criteria applied to hippocampal units, where 31.7% (1,820 of 5,735) did.

In [17]:
f_ls, f_hp = (LS.n_fields > 0), (HP.n_fields > 0)
print(f"LS rate maps with a field: {int(f_ls.sum())} of {len(LS)} = {f_ls.mean():.3f} (paper 0.053)")
print(f"Hippocampal rate maps with a field: {int(f_hp.sum())} of {len(HP)} = {f_hp.mean():.3f} (paper 0.317)")
tab = [[f_ls.sum(), (~f_ls).sum()], [f_hp.sum(), (~f_hp).sum()]]
chi = stats.chi2_contingency(tab)
print(f"Chi-squared {chi.statistic:.1f}, p = {chi.pvalue:.2e}")
print(pd.DataFrame({"LS": f_ls.groupby(LS.subject).mean(), "HPC": f_hp.groupby(HP.subject).mean(),
                    "n LS": f_ls.groupby(LS.subject).size(), "n HPC": f_hp.groupby(HP.subject).size()}).round(3).to_string())
print("\nVariants of the rate map and threshold:")
for col, name in (("n_fields", "Gaussian SD 4 bins, 20% threshold (main)"), ("n_fields_gauss5", "Gaussian SD 5 bins, 20%"),
                  ("n_fields_box5", "5-bin box map, 20%"), ("n_fields_thresh01", "Gaussian SD 4 bins, 1% (the code's default)"),
                  ("n_fields_nosd", "Gaussian SD 4 bins, 20%, without the mean < SD exclusion")):
    a, b = LS[col] > 0, HP[col] > 0
    c2 = stats.chi2_contingency([[a.sum(), (~a).sum()], [b.sum(), (~b).sum()]])
    print(f"  {name}: LS {a.mean():.3f}, hippocampus {b.mean():.3f}, chi-squared p = {c2.pvalue:.1e}")
LS rate maps with a field: 198 of 3694 = 0.054 (paper 0.053)
Hippocampal rate maps with a field: 531 of 5045 = 0.105 (paper 0.317)
Chi-squared 73.7, p = 8.92e-18
            LS    HPC  n LS   n HPC
subject                            
DT2      0.044  0.097   821  2373.0
DT5      0.062  0.101  1501   933.0
DT7      0.014  0.080    69   515.0
DT8      0.038    NaN   551     NaN
DT9      0.062  0.136   752  1224.0

Variants of the rate map and threshold:
  Gaussian SD 4 bins, 20% threshold (main): LS 0.054, hippocampus 0.105, chi-squared p = 8.9e-18
  Gaussian SD 5 bins, 20%: LS 0.049, hippocampus 0.116, chi-squared p = 2.8e-27
  5-bin box map, 20%: LS 0.058, hippocampus 0.063, chi-squared p = 4.0e-01
  Gaussian SD 4 bins, 1% (the code's default): LS 0.004, hippocampus 0.046, chi-squared p = 7.2e-31
  Gaussian SD 4 bins, 20%, without the mean < SD exclusion: LS 0.200, hippocampus 0.460, chi-squared p = 4.7e-139

Result: partially reproduced. 5.4% of LS rate maps have a place field, within tolerance of 5.3%, and fewer than in the hippocampus (chi-squared p = 8.9e-18), but only 10.5% of hippocampal rate maps have a field, against 31.7%. The hippocampal fraction is 8.0% to 13.6% per rat. With a Gaussian of SD 5 bins the fractions are 4.9% and 11.6%; with the 5-bin box map 5.8% and 6.3%, which do not differ (p = 0.40); with the 1% threshold of the code's default, 0.4% and 4.6%. The rule of bz_getPlaceFields1D that drops peaks whose SD across trials exceeds their mean accounts for most of the hippocampal shortfall: without it the fractions are 20.0% (LS) and 46.0% (hippocampus), so LS is then far above 5.3% and the hippocampus above 31.7%. Neither setting matches both of the paper's fractions. The rule is strict here probably because the rebuilt linearization gives about one position sample per bin and trial, which makes per-trial rates noisy.

Properties of hippocampal place fields (hpc-place-field-properties)¶

711 of 1,425 hippocampal neurons had at least one place field (1.27 fields per neuron on average); the median peak in-field rate was 8.5 Hz and the median field width 38 bins.

In [18]:
has = (HP.n_fields > 0).groupby(HP.neuron).any()
peaks = np.concatenate(HP.field_peaks_hz.dropna().values)
widths = np.concatenate(HP.field_widths.dropna().values)
nf = HP.groupby("neuron").n_fields.sum()
print(f"Hippocampal neurons with a field: {int(has.sum())} of {len(has)} = {has.mean():.3f} (paper 711 of 1,425 = 0.499)")
print(f"Fields per active neuron: mean {nf.mean():.2f} (paper 1.27)")
print(f"Median peak rate {np.median(peaks):.1f} Hz (paper 8.5); median width {np.median(widths):.0f} bins (paper 38); N = {len(peaks)} fields")
print("Per subject: fraction with a field", has.groupby([S.subject[n[0]] for n in has.index]).mean().round(3).to_dict())
for col, name in (("n_fields_gauss5", "Gaussian SD 5"), ("n_fields_box5", "5-bin box map"), ("n_fields_thresh01", "1% threshold"), ("n_fields_nosd", "no mean < SD exclusion")):
    print(f"Variant, {name}: {(HP[col] > 0).groupby(HP.neuron).any().mean():.3f} of neurons with a field")
Hippocampal neurons with a field: 301 of 1314 = 0.229 (paper 711 of 1,425 = 0.499)
Fields per active neuron: mean 0.47 (paper 1.27)
Median peak rate 8.4 Hz (paper 8.5); median width 39 bins (paper 38); N = 614 fields
Per subject: fraction with a field {'DT2': 0.199, 'DT5': 0.24, 'DT7': 0.202, 'DT9': 0.287}
Variant, Gaussian SD 5: 0.241 of neurons with a field
Variant, 5-bin box map: 0.147 of neurons with a field
Variant, 1% threshold: 0.124 of neurons with a field
Variant, no mean < SD exclusion: 0.623 of neurons with a field

Result: partially reproduced. The median peak rate, 8.4 Hz, and the median field width, 39 bins, are within tolerance of 8.5 Hz and 38 bins; but 22.9% of active hippocampal neurons have a field, against 49.9%, with 0.47 fields per neuron against 1.27. Under the variants of the map and threshold the fraction is 12.4% to 24.1%, and 62.3% without the rule dropping peaks whose SD across trials exceeds their mean (see ls-few-place-fields).

Stability of LS and hippocampal place fields (ls-place-fields-unstable)¶

The few LS rate maps with a place field were less stable across trials than CA1/CA3 place fields (median coefficient of variance 41.5 against 10; two-sample t test, p < 1e-20).

In [19]:
lf_, hf_ = LS[LS.n_fields > 0], HP[HP.n_fields > 0]
for name, col, scale in (("(a) SD over trials at the field peak, Hz", "field_peak_sd", 1), ("(b) SD over mean at the peak, %", "field_peak_cv", 100)):
    a, b = lf_[col] * scale, hf_[col] * scale
    t = stats.ttest_ind(a, b)
    print(f"{name}: LS median {a.median():.1f} (N = {len(a)}), hippocampus median {b.median():.1f} (N = {len(b)}); t = {t.statistic:.2f}, p = {t.pvalue:.2e}")
print("Paper: 41.5 against 10.")
(a) SD over trials at the field peak, Hz: LS median 3.5 (N = 198), hippocampus median 6.4 (N = 531); t = -7.76, p = 2.78e-14
(b) SD over mean at the peak, %: LS median 86.2 (N = 198), hippocampus median 83.6 (N = 531); t = 1.56, p = 1.19e-01
Paper: 41.5 against 10.

Result: not reproduced. Under neither reading are LS fields more variable than hippocampal ones. Under reading (a), the SD at the peak that makeFig2.m computes, the LS median (3.5 Hz) is below the hippocampal one (6.4 Hz, t = -7.76, p = 2.8e-14), the reverse of the claim. Under reading (b), SD over mean, the medians are 86.2% and 83.6% and do not differ (p = 0.12). Both readings are far from 41.5 and 10.

Smoothing scale of peak information (fig1e-phase-info-smaller-scale)¶

Hippocampal place fields reach their peak information at smaller smoothing scales for phase than for rate (medians 15 and 29 bins; two-sample t test, p < 1e-40).

In [20]:
info = [dict(x, session=i, subject=results[i]["summary"]["subject"]) for i, r in enumerate(results) for x in r.get("info", [])]
def smooth5(v):
    return lshpc.matlab_smooth(v, 5)
best_p = np.array([np.argmax(smooth5(x["phase"])) + 1 for x in info])
best_r = np.array([np.argmax(smooth5(x["rate"])) + 1 for x in info])
keep_p, keep_r = best_p < 49, best_r < 49
t = stats.ttest_ind(best_p[keep_p], best_r[keep_r])
print(f"Place fields with information curves: {len(info)}; kept (best smoothing below 49): phase {keep_p.sum()}, rate {keep_r.sum()}")
print(f"Median best smoothing: phase {np.median(best_p[keep_p]):.0f} bins, rate {np.median(best_r[keep_r]):.0f} bins (paper 15 and 29); "
      f"means {best_p[keep_p].mean():.1f} and {best_r[keep_r].mean():.1f}; t = {t.statistic:.2f}, p = {t.pvalue:.2e}")
print(f"Fields left out at 49 or more: phase {(~keep_p).sum()}, rate {(~keep_r).sum()}")
subj = np.array([x["subject"] for x in info])
for s_ in sorted(set(subj)):
    m = subj == s_
    print(f"  {s_}: N = {m.sum()}, median phase {np.median(best_p[m & keep_p]) if (m & keep_p).any() else np.nan}, "
          f"rate {np.median(best_r[m & keep_r]) if (m & keep_r).any() else np.nan}")
fig, ax = plt.subplots(figsize=(5, 3))
ax.hist(best_p[keep_p], np.arange(0, 51, 2), alpha=.6, label="phase"); ax.hist(best_r[keep_r], np.arange(0, 51, 2), alpha=.6, label="rate")
ax.set_xlabel("smoothing with peak information (bins)"); ax.set_ylabel("place fields"); ax.legend(); plt.show()
print("Plotted values: phase", best_p[keep_p].min(), "to", best_p[keep_p].max(), "| rate", best_r[keep_r].min(), "to", best_r[keep_r].max(), "bins; none outside the axes")
Place fields with information curves: 531; kept (best smoothing below 49): phase 525, rate 493
Median best smoothing: phase 10 bins, rate 17 bins (paper 15 and 29); means 12.1 and 19.3; t = -11.18, p = 1.94e-27
Fields left out at 49 or more: phase 6, rate 38
  DT2: N = 230, median phase 7.0, rate 16.0
  DT5: N = 94, median phase 13.0, rate 17.5
  DT7: N = 41, median phase 15.0, rate 19.0
  DT9: N = 166, median phase 13.0, rate 17.0
No description has been provided for this image
Plotted values: phase 1 to 47 | rate 1 to 48 bins; none outside the axes

Result: partially reproduced. Phase information peaks at smaller smoothing than rate information (medians 10 and 17 bins, t = -11.18, p = 1.9e-27), and in each rat, but both medians are below the paper's 15 and 29, and p does not reach 1e-40 with 531 fields. At the same nominal span the rate and phase smoothings differ slightly (MATLAB smooth drops an even span by one; circ_smoothTS uses 2 ceil(w/2) + 1 bins), as in the paper's code.

Information of phase and rate at fine and coarse scales (fig1g-phase-more-info-fine-scale)¶

At smoothing below 6 cm (about one theta cycle) phase carries more spatial information than rate in hippocampal place fields, and above 10 cm rate carries more.

In [21]:
P = np.array([x["phase"] / x["n_trials"] for x in info])
R = np.array([x["rate"] / x["n_trials"] for x in info])
rows = []
for w in lshpc.INFO_SMOOTHINGS:
    t = stats.ttest_ind(P[:, w - 1], R[:, w - 1])
    rows.append({"smoothing": w, "phase_minus_rate": (P[:, w - 1] - R[:, w - 1]).mean(), "p": t.pvalue})
D = pd.DataFrame(rows)
print(D[D.smoothing.isin([1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 30, 40, 50])].to_string(index=False))
fine = D[D.smoothing.isin([2, 3])]
coarse = D[D.smoothing >= 7]
print(f"\nFine (2 and 3 bins): phase above rate at p < 1e-5 in {int(((fine.phase_minus_rate > 0) & (fine.p < 1e-5)).sum())} of 2")
print(f"Coarse (7 to 50 bins): rate above phase at p < 0.05 in {int(((coarse.phase_minus_rate < 0) & (coarse.p < 0.05)).sum())} of {len(coarse)} "
      f"({((coarse.phase_minus_rate < 0) & (coarse.p < 0.05)).mean():.2f})")
print("Bin size: the median trial path over 200 bins is", round(float(np.nanmedian(S[S.position_unit_used == "cm"].path_length_median)) / 200, 2),
      "cm in the files with a scale (paper about 1.5 cm)")
 smoothing  phase_minus_rate            p
         1          0.006100 1.806744e-01
         2          0.018115 2.134525e-05
         3          0.005834 1.553831e-01
         4          0.005834 1.553831e-01
         5         -0.003479 4.243736e-01
         6         -0.003479 4.243736e-01
         7         -0.007554 9.081621e-02
        10         -0.012487 6.401212e-03
        15         -0.019879 1.999584e-05
        20         -0.022573 1.087465e-06
        30         -0.027117 3.612065e-09
        40         -0.031027 1.531080e-11
        50         -0.032728 7.630086e-13

Fine (2 and 3 bins): phase above rate at p < 1e-5 in 0 of 2
Coarse (7 to 50 bins): rate above phase at p < 0.05 in 42 of 44 (0.95)
Bin size: the median trial path over 200 bins is 1.12 cm in the files with a scale (paper about 1.5 cm)

Result: partially reproduced. At coarse smoothing (7 to 50 bins) rate carries more information than phase at p < 0.05 in 42 of 44 smoothings (95%, above the criterion's 80%), as the paper reports above 10 cm. At fine smoothing phase carries more, but not at p < 1e-5 (2 bins, +0.018, p = 2.1e-5; 3 bins, +0.006, p = 0.16). Bins here are about 1.1 cm, so 2 and 3 bins are below 6 cm.

Phase coding and LS depth (fig4d-depth-gradient)¶

The strength of phase coding relative to rate coding increases with recording depth within the LS, within sessions and across animals.

In [22]:
sd = LSd.groupby("session").apply(lambda g: (g.mse_phase - g.mse_rate).mean()).rename("diff").to_frame()
sd["subject"] = S.subject[sd.index].values
sd["depth"] = S.ls_depth[sd.index].values
rows = []
for subj, g in sd.groupby("subject"):
    if len(g) >= 4 and g.depth.nunique() > 1:
        r, p = stats.pearsonr(g.depth, g["diff"])
    else:
        r, p = np.nan, np.nan
    rows.append({"subject": subj, "sessions": len(g), "depth_range": f"{g.depth.min()}-{g.depth.max()}", "r": r, "p": p})
print(pd.DataFrame(rows).round(3).to_string(index=False))
c = sd.copy()
c["depth"] -= c.groupby("subject").depth.transform("mean")
c["diff"] -= c.groupby("subject")["diff"].transform("mean")
r, p = stats.pearsonr(c.depth, c["diff"])
print(f"Pooled, centred within animal: r = {r:.3f}, p = {p:.3f}, N = {len(c)} sessions")
r2, p2 = stats.pearsonr(sd.depth, sd["diff"])
print(f"Variant, pooled without centring: r = {r2:.3f}, p = {p2:.3f}")
sd2 = sd.copy(); sd2["depth"] = S.hpc_depth[sd.index].values
for subj, g in sd2.groupby("subject"):
    if len(g) >= 4 and g.depth.nunique() > 1:
        print(f"  variant with the second depth, {subj}: r = {stats.pearsonr(g.depth, g['diff'])[0]:.3f}")
c2 = sd2.copy()
c2["depth"] -= c2.groupby("subject").depth.transform("mean")
c2["diff"] -= c2.groupby("subject")["diff"].transform("mean")
r3, p3 = stats.pearsonr(c2.depth, c2["diff"])
print(f"Variant, second depth, pooled and centred within animal: r = {r3:.3f}, p = {p3:.3f}")
subject  sessions depth_range      r     p
    DT2         9   3324-3540 -0.704 0.034
    DT5        16    972-2124 -0.426 0.100
    DT7         3    288-1440    NaN   NaN
    DT8        17       0-612  0.239 0.356
    DT9        13       0-900 -0.620 0.024
Pooled, centred within animal: r = -0.365, p = 0.005, N = 58 sessions
Variant, pooled without centring: r = -0.102, p = 0.445
  variant with the second depth, DT2: r = -0.729
  variant with the second depth, DT5: r = -0.528
  variant with the second depth, DT8: r = 0.030
  variant with the second depth, DT9: r = -0.604
Variant, second depth, pooled and centred within animal: r = -0.268, p = 0.042

Result: partially reproduced. With depth and value centred within each rat, deeper LS sessions have more negative phase minus rate MSE (r = -0.365, p = 0.005, 58 sessions). Per rat r is negative in DT2 (-0.70), DT5 (-0.43) and DT9 (-0.62) but positive in DT8 (+0.24), so it does not hold in every rat. With the second depth of the name the per-rat signs are the same and the pooled r is -0.268 (p = 0.042); which depth is the LS probe's is an assumption (see the data check). The within-session part cannot be tested, as the dandiset gives no recording site per unit.

Onset phase of LS phase fields and depth (fig4e-onset-depth)¶

The theta phase at the onset of LS phase fields varies with recording depth (DT5 r = 0.38, DT9 r = 0.25, DT2 r = 0.27; circular-linear correlation, p < 0.001).

In [23]:
sig = LSd[sig_chance & LSd.onset_phase.notna()]
best = sig.loc[sig.groupby("neuron").mse_phase.idxmin()]
best = best.assign(depth=S.ls_depth[best.session].values)
print(f"Neurons with significant phase coding and an onset phase: {len(best)}")
for subj in ["DT5", "DT9", "DT2", "DT7", "DT8"]:
    g = best[best.subject == subj]
    if len(g) > 5 and g.depth.nunique() > 1:
        r, p = lshpc.circ_corrcl(g.onset_phase.values, g.depth.values)
        print(f"  {subj}: N = {len(g)} neurons, {g.session.nunique()} sessions, depths {g.depth.min()}-{g.depth.max()} um, r = {r:.3f}, p = {p:.2e}")
print("Paper: DT5 0.38, DT9 0.25, DT2 0.27, each p < 0.001.")
allc = sig.assign(depth=S.ls_depth[sig.session].values)
print("Variant, every significant condition:")
for subj in ["DT5", "DT9", "DT2"]:
    g = allc[allc.subject == subj]
    r, p = lshpc.circ_corrcl(g.onset_phase.values, g.depth.values)
    print(f"  {subj}: N = {len(g)}, r = {r:.3f}, p = {p:.2e}")
print("Variant, sessions whose theta channel has the rat's most common label (one reference region per rat):")
lab = S.theta_label[best.session].values
for subj in ["DT5", "DT9", "DT2"]:
    g = best[(best.subject == subj)]
    gl = lab[best.subject == subj]
    top = pd.Series(gl).value_counts(dropna=False).index[0]
    g = g[pd.Series(gl).eq(top).values] if top == top else g
    r, p = lshpc.circ_corrcl(g.onset_phase.values, g.depth.values)
    print(f"  {subj}: label {top}, N = {len(g)} neurons, {g.session.nunique()} sessions, depths {g.depth.min()}-{g.depth.max()} um, "
          f"r = {r:.3f}, p = {p:.2e}")
Neurons with significant phase coding and an onset phase: 396
  DT5: N = 169 neurons, 16 sessions, depths 972-2124 um, r = 0.082, p = 5.69e-01
  DT9: N = 98 neurons, 11 sessions, depths 0-900 um, r = 0.072, p = 7.76e-01
  DT2: N = 62 neurons, 9 sessions, depths 3324-3540 um, r = 0.118, p = 6.50e-01
  DT7: N = 10 neurons, 2 sessions, depths 288-576 um, r = 0.537, p = 2.36e-01
  DT8: N = 57 neurons, 15 sessions, depths 0-612 um, r = 0.112, p = 6.99e-01
Paper: DT5 0.38, DT9 0.25, DT2 0.27, each p < 0.001.
Variant, every significant condition:
  DT5: N = 360, r = 0.058, p = 5.48e-01
  DT9: N = 247, r = 0.102, p = 2.76e-01
  DT2: N = 89, r = 0.156, p = 3.38e-01
Variant, sessions whose theta channel has the rat's most common label (one reference region per rat):
  DT5: label hpc, N = 105 neurons, 10 sessions, depths 972-2052 um, r = 0.027, p = 9.61e-01
  DT9: label hpc, N = 68 neurons, 7 sessions, depths 0-468 um, r = 0.170, p = 3.74e-01
  DT2: label unknown, N = 62 neurons, 9 sessions, depths 3324-3540 um, r = 0.118, p = 6.50e-01

Result: not reproduced. The circular-linear correlation between onset phase and LS depth is r = 0.082 (p = 0.57) in DT5, 0.072 (p = 0.78) in DT9 and 0.118 (p = 0.65) in DT2, against 0.38, 0.25 and 0.27 at p < 0.001. Using every significant condition gives the same, and so does keeping only the sessions whose theta channel has the rat's most common label (hpc in DT5 and DT9; r = 0.027 and 0.170, p = 0.96 and 0.37), which removes the switches between hpc and ca3 references. The test rests on the session depth (the first number in the session name) and on a theta channel chosen per session, which may differ in layer between sessions. That the first depth is the LS depth is an assumption (see fig4d-depth-gradient).

LS-hippocampal theta coherence along the run (fig6c-ca3-coherence-increases)¶

Theta phase coherence between LS and the CA3 pyramidal layer increases from the beginning to the end of the run, while coherence between LS and CA1 stays relatively flat.

In [24]:
rows = []
for i, r in enumerate(results):
    f6 = r.get("fig6")
    if not f6:
        continue
    sm = r["summary"]
    labels = sm["unit_locations"]
    groups = (["CA3"] if "ca3" in labels else []) + (["CA1"] if ("hpc" in labels or "ca1" in labels) else [])
    groups = groups or ["none"]   # no hippocampal units: left out of the main test, kept for a variant
    seg = np.arange(lshpc.N_SEGMENTS)
    ok = np.isfinite(f6["coherence"])
    ok2 = np.isfinite(f6["cfc"])
    for group in groups:
        rows.append({"session": i, "subject": sm["subject"], "group": group, "channel": S.theta_label[i],
                     "coh_mean": np.nanmean(f6["coherence"]), "coh_slope": np.polyfit(seg[ok], f6["coherence"][ok], 1)[0] if ok.sum() > 2 else np.nan,
                     "cfc_mean": np.nanmean(f6["cfc"]), "cfc_slope": np.polyfit(seg[ok2], f6["cfc"][ok2], 1)[0] if ok2.sum() > 2 else np.nan,
                     "coh": f6["coherence"], "cfc": f6["cfc"]})
F6all = pd.DataFrame(rows)
F6 = F6all[F6all.group != "none"]
print("Sessions by group and subject (CA3: units labelled ca3; CA1: units labelled hpc):")
print(F6.groupby(["group", "subject"]).size().to_string())
print("Left out, no hippocampal units:", F6all[F6all.group == "none"].groupby("subject").size().to_dict())
print("Label of the hippocampal channel by group:", F6.groupby("group").channel.value_counts().to_dict())
for g in ("CA3", "CA1"):
    x = F6[F6.group == g].coh_slope.dropna()
    w = stats.wilcoxon(x)
    print(f"{g}: N = {len(x)} sessions, median coherence slope {x.median():.4f} per segment, signed-rank p = {w.pvalue:.3f}, positive in {(x > 0).sum()}")
mw = stats.mannwhitneyu(F6[F6.group == "CA3"].coh_slope.dropna(), F6[F6.group == "CA1"].coh_slope.dropna(), alternative="greater")
print(f"CA3 slopes above CA1 slopes: Mann-Whitney p = {mw.pvalue:.3f}")
print("Mean coherence by segment:")
print(pd.DataFrame({g: np.nanmean(np.vstack(F6[F6.group == g].coh.values), 0) for g in ("CA3", "CA1")}).round(3).T.to_string())
print("Per subject, median slope:", F6.groupby(["group", "subject"]).coh_slope.median().round(4).to_dict())
print("Within animal, CA3 slopes above CA1 slopes (Mann-Whitney):")
for subj in ("DT5", "DT9"):
    g = F6[F6.subject == subj]
    a, b = g[g.group == "CA3"].coh_slope.dropna(), g[g.group == "CA1"].coh_slope.dropna()
    print(f"  {subj}: CA3 N = {len(a)}, median {a.median():.4f}; CA1 N = {len(b)}, median {b.median():.4f}; p = {stats.mannwhitneyu(a, b, alternative='greater').pvalue:.3f}")
F6v = F6all.assign(group=F6all.group.replace({"none": "CA1"}))
mwv = stats.mannwhitneyu(F6v[F6v.group == "CA3"].coh_slope.dropna(), F6v[F6v.group == "CA1"].coh_slope.dropna(), alternative="greater")
print(f"Variant, sessions without hippocampal units counted as CA1 (as before revision, N = {int((F6v.group == 'CA1').sum())}): CA3 above CA1, p = {mwv.pvalue:.3f}")
Sessions by group and subject (CA3: units labelled ca3; CA1: units labelled hpc):
group  subject
CA1    DT2        10
       DT5        10
       DT7         7
       DT9         9
CA3    DT5         6
       DT9         5
Left out, no hippocampal units: {'DT7': 2, 'DT8': 17}
Label of the hippocampal channel by group: {('CA1', 'hpc'): 24, ('CA1', 'unknown'): 12, ('CA3', 'ca3'): 11}
CA3: N = 11 sessions, median coherence slope 0.0026 per segment, signed-rank p = 0.831, positive in 7
CA1: N = 36 sessions, median coherence slope -0.0018 per segment, signed-rank p = 0.346, positive in 13
CA3 slopes above CA1 slopes: Mann-Whitney p = 0.348
Mean coherence by segment:
         0      1      2      3      4      5      6      7      8      9
CA3  0.748  0.738  0.754  0.747  0.738  0.749  0.744  0.746  0.743  0.759
CA1  0.798  0.795  0.796  0.793  0.777  0.783  0.782  0.781  0.784  0.807
Per subject, median slope: {('CA1', 'DT2'): -0.0012, ('CA1', 'DT5'): -0.0024, ('CA1', 'DT7'): -0.0029, ('CA1', 'DT9'): 0.0027, ('CA3', 'DT5'): 0.0035, ('CA3', 'DT9'): -0.0081}
Within animal, CA3 slopes above CA1 slopes (Mann-Whitney):
  DT5: CA3 N = 6, median 0.0035; CA1 N = 10, median -0.0024; p = 0.184
  DT9: CA3 N = 5, median -0.0081; CA1 N = 9, median 0.0027; p = 0.905
Variant, sessions without hippocampal units counted as CA1 (as before revision, N = 55): CA3 above CA1, p = 0.235

Result: not reproduced. Theta phase locking between the hippocampal and LS channels does not rise along the run in the 11 CA3 sessions (median slope 0.0026 per segment, signed-rank p = 0.83), and CA3 slopes are not above those of the 36 CA1 sessions (p = 0.35). Within DT5 (p = 0.18) and DT9 (p = 0.91) CA3 slopes are not above CA1 slopes either. The measure is a phase locking value, not the paper's multitaper coherence, and the hippocampal channel is chosen here, not the paper's pyramidal layer site.

Theta-gamma coupling between hippocampus and LS (fig6d-cfc-stronger-ca3)¶

Coupling between hippocampal theta phase and LS gamma amplitude increases along the run for both CA1 and CA3, and is stronger for CA3-LS than for CA1-LS.

In [25]:
mw = stats.mannwhitneyu(F6[F6.group == "CA3"].cfc_mean.dropna(), F6[F6.group == "CA1"].cfc_mean.dropna(), alternative="greater")
print(f"Mean coupling (circular-linear r): CA3 median {F6[F6.group == 'CA3'].cfc_mean.median():.4f}, CA1 median {F6[F6.group == 'CA1'].cfc_mean.median():.4f}; "
      f"CA3 above CA1, Mann-Whitney p = {mw.pvalue:.3f}")
for g in ("CA3", "CA1"):
    x = F6[F6.group == g].cfc_slope.dropna()
    w = stats.wilcoxon(x)
    print(f"{g}: N = {len(x)}, median slope {x.median():.5f} per segment, signed-rank p = {w.pvalue:.3f}, positive in {(x > 0).sum()}")
print("Mean coupling by segment:")
print(pd.DataFrame({g: np.nanmean(np.vstack(F6[F6.group == g].cfc.values), 0) for g in ("CA3", "CA1")}).round(4).T.to_string())
print("Per subject, mean coupling:", F6.groupby(["group", "subject"]).cfc_mean.median().round(4).to_dict())
print("Within animal, CA3 coupling above CA1 coupling (Mann-Whitney):")
for subj in ("DT5", "DT9"):
    g = F6[F6.subject == subj]
    a, b = g[g.group == "CA3"].cfc_mean.dropna(), g[g.group == "CA1"].cfc_mean.dropna()
    print(f"  {subj}: CA3 N = {len(a)}, median {a.median():.4f}; CA1 N = {len(b)}, median {b.median():.4f}; p = {stats.mannwhitneyu(a, b, alternative='greater').pvalue:.3f}")
mwv = stats.mannwhitneyu(F6v[F6v.group == "CA3"].cfc_mean.dropna(), F6v[F6v.group == "CA1"].cfc_mean.dropna(), alternative="greater")
print(f"Variant, sessions without hippocampal units counted as CA1 (as before revision): CA3 above CA1, p = {mwv.pvalue:.3f}")
Mean coupling (circular-linear r): CA3 median 0.0594, CA1 median 0.0511; CA3 above CA1, Mann-Whitney p = 0.089
CA3: N = 11, median slope 0.00359 per segment, signed-rank p = 0.002, positive in 10
CA1: N = 36, median slope 0.00125 per segment, signed-rank p = 0.001, positive in 24
Mean coupling by segment:
          0       1       2       3       4       5       6       7       8       9
CA3  0.0390  0.0415  0.0531  0.0505  0.0653  0.0793  0.0829  0.0817  0.0740  0.0568
CA1  0.0395  0.0479  0.0456  0.0581  0.0509  0.0645  0.0721  0.0617  0.0573  0.0574
Per subject, mean coupling: {('CA1', 'DT2'): 0.0274, ('CA1', 'DT5'): 0.0568, ('CA1', 'DT7'): 0.0903, ('CA1', 'DT9'): 0.0568, ('CA3', 'DT5'): 0.0725, ('CA3', 'DT9'): 0.049}
Within animal, CA3 coupling above CA1 coupling (Mann-Whitney):
  DT5: CA3 N = 6, median 0.0725; CA1 N = 10, median 0.0568; p = 0.011
  DT9: CA3 N = 5, median 0.0490; CA1 N = 9, median 0.0568; p = 0.880
Variant, sessions without hippocampal units counted as CA1 (as before revision): CA3 above CA1, p = 0.041

Result: not reproduced. Coupling between hippocampal theta phase and LS gamma amplitude rises along the run in both groups (signed-rank p = 0.002 in 11 CA3 sessions and 0.001 in 36 CA1 sessions), but it is not higher in CA3 than in CA1 sessions at p < 0.05 (medians 0.059 and 0.051, Mann-Whitney p = 0.089), which the criterion needs for a full or a partial outcome. Within DT5 CA3 coupling is higher (p = 0.011); within DT9 it is not (p = 0.88). Before revision, with the 19 sessions without hippocampal units counted as CA1, p was 0.041.

Ensemble decoding (figs7-ensemble-ls-phase-best)¶

The firing phases of ensembles of simultaneously recorded LS neurons read out position better than the firing phases or rates of an equal number of hippocampal neurons (p < 0.001 at 15 to 25 neurons).

In [26]:
E = pd.DataFrame([dict(x, session=i, subject=results[i]["summary"]["subject"]) for i, r in enumerate(results) for x in r.get("ensemble", [])])
print("Conditions with at least 15 included LS and 15 hippocampal units:", E.drop_duplicates(["session", "condition"]).shape[0],
      "in", E.session.nunique(), "sessions;", E.drop_duplicates(["session", "condition"]).groupby("subject").size().to_dict())
for n, g in E.groupby("size"):
    v = {k: np.concatenate(g[k].values) for k in ("ls_phase", "ls_rate", "hpc_phase", "hpc_rate")}
    print(f"size {n}: {len(g)} conditions; mean MSE LS phase {v['ls_phase'].mean():.0f}, LS rate {v['ls_rate'].mean():.0f}, "
          f"HPC phase {v['hpc_phase'].mean():.0f}, HPC rate {v['hpc_rate'].mean():.0f}")
    for other in ("hpc_phase", "hpc_rate"):
        lower = stats.ttest_ind(v["ls_phase"], v[other], alternative="less")
        higher = stats.ttest_ind(v["ls_phase"], v[other], alternative="greater")
        print(f"    LS phase minus {other}: {v['ls_phase'].mean() - v[other].mean():+.0f}; one-sided p, LS phase lower = {lower.pvalue:.2g}, "
              f"LS phase higher = {higher.pvalue:.2g}")
Conditions with at least 15 included LS and 15 hippocampal units: 65 in 13 sessions; {'DT2': 32, 'DT5': 22, 'DT9': 11}
size 15: 65 conditions; mean MSE LS phase 4738, LS rate 4418, HPC phase 4597, HPC rate 3119
    LS phase minus hpc_phase: +141; one-sided p, LS phase lower = 1, LS phase higher = 0.00058
    LS phase minus hpc_rate: +1619; one-sided p, LS phase lower = 1, LS phase higher = 3e-186
size 20: 7 conditions; mean MSE LS phase 4260, LS rate 4647, HPC phase 3971, HPC rate 2592
    LS phase minus hpc_phase: +290; one-sided p, LS phase lower = 1, LS phase higher = 0.0016
    LS phase minus hpc_rate: +1668; one-sided p, LS phase lower = 1, LS phase higher = 1e-38
size 25: 3 conditions; mean MSE LS phase 3459, LS rate 4195, HPC phase 3746, HPC rate 2259
    LS phase minus hpc_phase: -288; one-sided p, LS phase lower = 0.0075, LS phase higher = 0.99
    LS phase minus hpc_rate: +1200; one-sided p, LS phase lower = 1, LS phase higher = 1.3e-12

Result: not reproduced. In 65 conditions from 13 sessions with at least 15 active LS and hippocampal units, LS phase ensembles of 15 units have a higher MSE (4,738) than hippocampal phase ensembles (4,597; one-sided p = 0.00058 for LS phase higher) and hippocampal rate ensembles (3,119; p = 3e-186). The same holds at 20 units (7 conditions). Only at 25 units (3 conditions) is the LS phase MSE lower than the hippocampal phase MSE (3,459 against 3,746, one-sided p = 0.0075), and it stays above the hippocampal rate MSE (2,259). That p value treats the ensemble draws within each of the 3 conditions as independent, so it overstates the evidence; at 15 and 20 units the direction is the reverse of the claim in any case.

Hippocampal-LS assemblies, on a sample of pairs (fig5-assemblies)¶

Spike trains of hippocampal neurons predicted LS firing in 18.5% (2,087 of 11,264) of hippocampal-LS pairs, with a median optimal timescale of 25 ms.

The peer prediction is run on a random sample of about 1% of the pairs, as all of them do not fit the time limit (the estimate is printed below). The procedure is in lshpc.py and the claims file.

In [27]:
AS = pd.DataFrame([dict(x, session=i, subject=results[i]["summary"]["subject"]) for i, r in enumerate(results) for x in r.get("assemblies", [])])
n_total = sum(r.get("assembly_pairs_total", 0) for r in results)
pairs_units = sum(len(set(LS[LS.session == s_].unit)) * len(set(HP[HP.session == s_].unit)) for s_ in S.session)
print(f"Pairs of active hippocampal and LS units recorded together: {pairs_units:,}; pairs active in the same condition, "
      f"counted per condition: {n_total:,} (paper 11,264 pairs)")
print(f"Sampled with p = {lshpc.ASSEMBLY_SAMPLE_P}: {len(AS)} pairs in {AS.session.nunique()} sessions; per subject {AS.groupby('subject').size().to_dict()}")
print("Fits without a finite strength:", int((~np.isfinite(AS.strength)).sum()))
is_a = AS.strength >= lshpc.ASSEMBLY_THRESHOLD
k, n = int(is_a.sum()), len(AS)
ci = stats.binomtest(k, n).proportion_ci(0.95)
print(f"Assemblies (strength at least 4): {k} of {n} = {k / n:.3f}, 95% interval {ci.low:.3f} to {ci.high:.3f} | paper 0.185")
print(f"Median best window of the assemblies: {AS[is_a].window_ms.median():.1f} ms (paper 25); of all sampled pairs {AS.window_ms.median():.1f} ms")
print("Best windows of the assemblies (ms: pairs):", AS[is_a].window_ms.value_counts().sort_index().to_dict())
print("Per subject, fraction of assemblies:", is_a.groupby(AS.subject).mean().round(3).to_dict())
for th in (1.5, 2, 4, 8):
    print(f"  threshold {th}: {(AS.strength >= th).mean():.3f} of sampled pairs")
print(f"Real gain above all 10 shuffles (strength above 1): {(AS.strength > 1).mean():.3f} of sampled pairs")
it = AS.strength_tuning >= lshpc.ASSEMBLY_THRESHOLD
ci2 = stats.binomtest(int(it.sum()), n).proportion_ci(0.95)
print(f"Variant, with the LS unit's rate map at the current position as a covariate: {int(it.sum())} of {n} = {it.mean():.3f} "
      f"(95% interval {ci2.low:.3f} to {ci2.high:.3f}); median best window {AS[it].window_ms_tuning.median():.1f} ms; "
      f"threshold 1.5: {(AS.strength_tuning >= 1.5).mean():.3f}; pairs found by both: {int((it & is_a).sum())}")
sec = AS.seconds.mean()
print(f"Time per pair: {sec:.2f} s on one process; all {n_total:,} pairs would take about {n_total * sec / 3600:.0f} process-hours")
Pairs of active hippocampal and LS units recorded together: 20,979; pairs active in the same condition, counted per condition: 70,898 (paper 11,264 pairs)
Sampled with p = 0.01: 670 pairs in 39 sessions; per subject {'DT2': 408, 'DT5': 157, 'DT7': 5, 'DT9': 100}
Fits without a finite strength: 0
Assemblies (strength at least 4): 35 of 670 = 0.052, 95% interval 0.037 to 0.072 | paper 0.185
Median best window of the assemblies: 20.0 ms (paper 25); of all sampled pairs 15.0 ms
Best windows of the assemblies (ms: pairs): {1: 5, 10: 2, 15: 7, 20: 7, 30: 3, 40: 1, 100: 1, 150: 9}
Per subject, fraction of assemblies: {'DT2': 0.039, 'DT5': 0.102, 'DT7': 0.0, 'DT9': 0.03}
  threshold 1.5: 0.194 of sampled pairs
  threshold 2: 0.127 of sampled pairs
  threshold 4: 0.052 of sampled pairs
  threshold 8: 0.018 of sampled pairs
Real gain above all 10 shuffles (strength above 1): 0.354 of sampled pairs
Variant, with the LS unit's rate map at the current position as a covariate: 37 of 670 = 0.055 (95% interval 0.039 to 0.075); median best window 15.0 ms; threshold 1.5: 0.197; pairs found by both: 29
Time per pair: 1.18 s on one process; all 70,898 pairs would take about 23 process-hours

Result: not reproduced. In a random sample of 670 of the 70,898 hippocampal-LS pairs active in the same condition, 35 (5.2%, 95% interval 3.7% to 7.2%) form an assembly of strength at least 4, against 18.5%, and the median best window of the assemblies is 20 ms, against 25 ms. The real gain beats all ten shuffles in 35.4% of the pairs. This cannot be compared with 1 in 11, since the window is chosen to maximise the real fit and the shuffles are run only at that window, so the real fit and the shuffles are not exchangeable without coupling. With a threshold of 1.5 the fraction is 19.4%. Position enters the fit as one linear term, so shared spatial tuning is not removed; adding the LS unit's rate map at the current position as a covariate gives 5.5% (95% interval 3.9% to 7.5%; 29 of the 35 assemblies found again), so the linear coding does not account for the low fraction. The bin size (1 ms), the Gaussian kernel and the window grid are choices made here, as the Methods do not give them and the paper's assembly code is not public. Most sampled pairs come from DT2 (408 of 670), and the pairs are counted per condition, as the Methods imply ("Each neuron pair has a single assembly strength value, determined by all spikes that occur during a single block of trials").

Peak information of LS and hippocampal rate maps (ls-information-lower)¶

LS rate maps have lower peak information rates than hippocampal place field maps (0.4 against 1.7 bits/cm; p < 1e-100).

In [28]:
S["cm_per_bin"] = np.where(S.position_unit_used == "cm", S.path_length_median / lshpc.N_BINS, np.nan)
I = A.assign(cm_per_bin=S.cm_per_bin[A.session].values)
print("Included maps left out for positions in pixels (DT2):", int(I.cm_per_bin.isna().sum()))
I = I[I.cm_per_bin.notna()]
li, hi = I[I.region == "ls"], I[(I.region == "hpc") & (I.n_fields > 0)]
a, b = li.info_peak_bits / li.cm_per_bin, hi.info_peak_bits / hi.cm_per_bin
t = stats.ttest_ind(a, b)
print(f"LS rate maps: N = {len(a)}, mean {a.mean():.3f}, median {a.median():.3f} bits/cm (paper 0.4)")
print(f"Hippocampal place-field maps: N = {len(b)}, mean {b.mean():.3f}, median {b.median():.3f} bits/cm (paper 1.7)")
print(f"LS against hippocampus: t = {t.statistic:.1f}, p = {t.pvalue:.1e}")
print("Bin size, cm: median", round(float(I.drop_duplicates("session").cm_per_bin.median()), 2), "| range",
      round(float(I.cm_per_bin.min()), 2), "to", round(float(I.cm_per_bin.max()), 2))
print("Per subject, mean bits/cm:", pd.DataFrame({"LS": a.groupby(li.subject).mean(), "HPC fields": b.groupby(hi.subject).mean()}).round(3).to_dict())
ha = I[I.region == "hpc"]
print(f"Variant, every included hippocampal map: mean {(ha.info_peak_bits / ha.cm_per_bin).mean():.3f} bits/cm")
print(f"In bits per bin: LS mean {li.info_peak_bits.mean():.3f}, hippocampal fields {hi.info_peak_bits.mean():.3f} (at most log2(7) = {np.log2(7):.2f})")
Included maps left out for positions in pixels (DT2): 3194
LS rate maps: N = 2873, mean 0.632, median 0.556 bits/cm (paper 0.4)
Hippocampal place-field maps: N = 301, mean 1.490, median 1.435 bits/cm (paper 1.7)
LS against hippocampus: t = -40.3, p = 6.0e-287
Bin size, cm: median 1.12 | range 0.65 to 1.45
Per subject, mean bits/cm: {'LS': {'DT5': 0.657, 'DT7': 0.516, 'DT8': 0.587, 'DT9': 0.625}, 'HPC fields': {'DT5': 1.603, 'DT7': 1.063, 'DT8': nan, 'DT9': 1.532}}
Variant, every included hippocampal map: mean 0.876 bits/cm
In bits per bin: LS mean 0.713, hippocampal fields 1.724 (at most log2(7) = 2.81)

Result: partially reproduced. LS rate maps carry less peak information than hippocampal place-field maps (means 0.632 and 1.490 bits/cm, t = -40.3, p = 6.0e-287, below the paper's 1e-100), but neither value is within tolerance of 0.4 and 1.7 under either reading (medians 0.556 and 1.435). The measure is that of fig1e (7 levels); the paper's normalization of it is not public, so the scale of these values is uncertain. DT2 is left out for its positions in pixels.

Blocked claims¶

  • fig5g-assembly-neurons-stronger-phase and fig6e-assembly-position need the assembly strength of every pair: which LS neurons take part in any assembly, and the strengths of all CA1 and CA3 place cells paired with LS. At about 0.6 s per pair on one process in this run (1.2 s in the previous one; printed under fig5-assemblies) the 70,898 pairs take about 12 process-hours, beyond the time limit, so both are blocked as not runnable. Sampling LS neurons and running all of their pairs (about 89 per neuron) would test them on part of the data; that analysis was not run in this attempt.
  • speed-independent: the paper does not define the rate of phase precession or its test of speed modulation, and no code for it is public. The data needed are in the dandiset.
  • figs6-reference-frame: no file marks a maze rotation (see the data check).
  • fig7-dynamic-weighting-model: a simulation that uses no recorded data.

Summary¶

Claim Outcome
ls-neuron-count Reproduced
hpc-unit-count Partially reproduced
ls-active-neurons Reproduced
fig2-ls-phase-vs-shuffle Not reproduced
fig2-ls-phase-beats-rate Not reproduced
fig2e-ls-phase-lower-mse Reproduced
fig2fg-mse-difference Partially reproduced
fig1i-hpc-rate-phase-equivalent Not reproduced
ls-few-place-fields Partially reproduced
hpc-place-field-properties Partially reproduced
ls-place-fields-unstable Not reproduced
fig1e-phase-info-smaller-scale Partially reproduced
fig1g-phase-more-info-fine-scale Partially reproduced
fig4d-depth-gradient Partially reproduced
fig4e-onset-depth Not reproduced
fig6c-ca3-coherence-increases Not reproduced
fig6d-cfc-stronger-ca3 Not reproduced
figs7-ensemble-ls-phase-best Not reproduced
fig5-assemblies Not reproduced (on a sample of pairs)
ls-information-lower Partially reproduced
fig5g-assembly-neurons-stronger-phase, fig6e-assembly-position Blocked: not runnable
speed-independent Blocked: methods underspecified
figs6-reference-frame Blocked: metadata insufficient
fig7-dynamic-weighting-model Blocked: other

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.

How the analysis differs from the paper's.

  • The paper's linearized behaviour, trial conditions and choice of CA1 channel are not in the dandiset. Positions are linearized here by the fraction of each trial's path (200 bins, about 1.1 cm), conditions are formed from trial type, direction and start and end sites, and the theta channel is the hippocampal channel with high theta and the most 100 to 250 Hz power. In the 11 sessions with ca3 channels it is a CA3 channel, and in DT5 its theta rhythm is weak.
  • The per-cell decoder follows the paper's scratch code; the function that bins spike phases is not public, and the circular mean per bin is used.
  • Place fields follow bz_getPlaceFields1D on the Gaussian rate map of bz_firingMap1D (SD 4 bins), with the Methods' limits converted to bins at 1.5 cm. This finds a third of the paper's share of hippocampal fields; without the code's rule dropping peaks whose SD across trials exceeds their mean it finds more than the paper in both regions (46.0% hippocampal, 20.0% LS).
  • The information measure of Figure 1 and of the information rates is built from the Methods' formula with choices fixed in the claims file; the paper's function is not public.
  • Coherence in Figure 6 is a phase locking value of the 4 to 12 Hz phases, not multitaper coherence.
  • Only the trials are read from the LFP, with 1 s of padding for filtering.
  • Assemblies (Figure 5) are computed on a random 1% of the pairs, with a bin size, kernel and window grid chosen here; the claims that need every pair (Figure 5G, 6E) were not tested.

What was found about the dandiset.

  • The paper's processed behaviour (linearized position and trial conditions), the CA1 channel per session, and the unit recording sites are not in the dandiset. No session has both CA1 and CA3 channels labelled, where the paper's Figure 6A has sessions with both.
  • Eight DT8 files state positions in mm but hold metres; in every file the z column of position is a copy of y; eight of eleven DT2 files repeat or reverse position timestamps; DT2 positions are in pixels with no scale; the head-orientation quaternion is stated in metres.
  • DT2 electrodes are all labelled unknown; DT7 20170317 has 43 units with no region label; DT7 20170324 has no units; 11 units hold spike times out of order.
  • The depths in the session names are not described; the first is taken as the LS depth.
  • DT9 20170501's trials do not match its positions; DT8 20170207 and 20170224 have trials without type or direction.
  • The units labelled hpc (2,593) are 12.9% more than the paper's 2,297 CA1 units.
  • In the script that writes the paper's place-field files (scratch_07_25_17_calc_firingMaps.m), the file the figures load is named for a 20% threshold, but no threshold is passed, so the function's default of 1% applies.