94 lines
6.9 KiB
Python
94 lines
6.9 KiB
Python
"""Register fixed conditional audit before reading PN contribution results."""
|
|
from datetime import datetime, timezone
|
|
import platform
|
|
import subprocess
|
|
import sys
|
|
import numpy as np
|
|
import pandas as pd
|
|
from context import (ROOT, MODEL, EXP, AH, AH_MODEL, AG, AG_MODEL, META, COEFF,
|
|
GROUPS, read, save, digest, sources, integrity, load_module)
|
|
|
|
|
|
def main():
|
|
assert not EXP.exists() or not any(EXP.iterdir()), 'Populated audit directory must not be reused'
|
|
assert read(AH / 'audit/final-status.json')['status'] == 'PASS-CONDITIONAL-KC-DRIVE-AUDIT'
|
|
assert read(AG / 'audit/final-status.json')['numerical_gate_pass']
|
|
for sub in ('protocol', 'regression', 'trials', 'audit', 'logs'):
|
|
(EXP / sub).mkdir(parents=True, exist_ok=False)
|
|
test_command = [sys.executable, '-B', '-m', 'unittest', '-v',
|
|
'test_pn_observer', 'test_apl_sources', 'test_structure_metrics', 'test_harness',
|
|
'test_validate_events', 'test_publication']
|
|
tested = subprocess.run(test_command, cwd=MODEL, capture_output=True, text=True)
|
|
with (EXP / 'regression/unit-tests.log').open('x') as f:
|
|
f.write(tested.stdout + tested.stderr)
|
|
save(EXP / 'regression/unit-tests.json', dict(command=test_command, exit_code=tested.returncode,
|
|
pass_all=tested.returncode == 0, sha256=digest(EXP / 'regression/unit-tests.log')))
|
|
assert tested.returncode == 0
|
|
paths = [AH / 'manifest.json', AH / 'checksums.sha256', AH_MODEL / 'manifest.json',
|
|
AH_MODEL / 'checksums.sha256', AH_MODEL / 'replay_core.py', AH_MODEL / 'populations.py',
|
|
AG / 'manifest.json', AG / 'checksums.sha256', AG_MODEL / 'manifest.json',
|
|
AG_MODEL / 'checksums.sha256', META, COEFF,
|
|
ROOT / 'datasets/male-cns-v1.0/processed/neuron-only/gpu/csr-weights.int64.npy']
|
|
save(EXP / 'protocol/preregistered.json', dict(
|
|
timestamp_utc=datetime.now(timezone.utc).isoformat(), sources=sources(),
|
|
inputs=[dict(path=str(p.relative_to(ROOT)), sha256=digest(p)) for p in paths],
|
|
parent_commit=subprocess.check_output(['git', '-C', str(ROOT), 'rev-parse', 'HEAD'], text=True).strip(),
|
|
scope='Post-outcome conditional PN/APL source audit; no new whole-brain simulation or learning',
|
|
previous_KC_outcome_known=True, before_PN_contribution_accounting=True,
|
|
new_GPU_use=False, max_threads=4, output_budget_bytes=2 * 1024**3,
|
|
per_trial_first_arrival_row_limit=1000000, truncation_allowed=False,
|
|
exact_gate='All PN events/counts/final v,g,ref; fixture pre/post histories; 12 deterministic accounting repeats',
|
|
APL_gate='Source float64 mathematical accounting within prior standard-float32 analytic roundoff bounds; not CUDA bitwise replay',
|
|
hypotheses={
|
|
'temporal_precedence': 'For every trial and every KC first spike, non-design PN spike must be strictly earlier; equals/after/absent retained',
|
|
'direct_PN_KC_arrival': 'PN source tick+18 strictly less than KC first spike; same tick arrival is after threshold',
|
|
'APL_source_precedence': 'Group h write at tick s affects only KC threshold ticks greater than s',
|
|
'APL_share': 'Cumulative group shares are descriptive float64; no accumulated source-share error bound or robust-majority claim',
|
|
'odor_structure': 'Fixed 686-dimensional counts; secondary fixed outside-six-odor-design-union subset; no activity-fraction or learning gate'},
|
|
attribution_limits=['Accepted edge antecedents are not proof of single-neuron necessity or intervention causality',
|
|
'Non-design means not in static design targets; does not mean noise or biologically incorrect',
|
|
'Source-V lanes are non-feedback accounting with initial/constant/request/reset/roundoff lanes',
|
|
'APL input matrix is legacy nonnegative raw-contact-normalized engineering mapping, not signed LIF current',
|
|
'No CAL per-tick target state was independently saved; final states and events only',
|
|
'Fixtures generated h for 4064 KC but applied only to fixture KC'],
|
|
python=sys.version, numpy=np.__version__, pandas=pd.__version__, machine=platform.machine(),
|
|
longdouble_mantissa_bits=int(np.finfo(np.longdouble).nmant)))
|
|
save(EXP / 'regression/old-integrity-before.json', integrity())
|
|
population = load_module('frozen_population_ai', AH_MODEL / 'populations.py')
|
|
assert digest(META) == population.METADATA_SHA256
|
|
meta = pd.read_parquet(META).sort_values('neuron_idx').reset_index(drop=True)
|
|
labels, report = population.classify(meta)
|
|
assert report['pass_all']
|
|
for name, count in (('ALLN', 420), ('ALIN', 24), ('ALON', 14), ('olfactory', 2639)):
|
|
selected = (meta.annotation_class == name).fillna(False).to_numpy(dtype=bool)
|
|
assert int(selected.sum()) == count and np.all(labels[selected] == 'other')
|
|
labels[selected] = 'olfactory_sensory' if name == 'olfactory' else name
|
|
assert set(np.unique(labels)).issubset(GROUPS)
|
|
for label, fname, count in (('KC', 'kc_globals.npy', 4064), ('APL', 'apl_globals.npy', 2), ('ALPN', 'pn_globals.npy', 686)):
|
|
observed = np.flatnonzero(labels == label).astype(np.int32)
|
|
assert len(observed) == count and np.array_equal(observed, np.load(AG / 'apl-bundle' / fname))
|
|
report.update(refined_exact_class_counts={label: int((labels == label).sum()) for label in GROUPS},
|
|
refinement='AH anatomical classifier, then exact ALLN/ALIN/ALON/olfactory classes split only from other; no name-prefix guessing')
|
|
save(EXP / 'protocol/population-audit.json', report)
|
|
save(EXP / 'protocol/metadata-schema.json', {c: dict(dtype=str(meta[c].dtype), nulls=int(meta[c].isna().sum())) for c in meta})
|
|
meta[['neuron_idx', 'body_id', 'annotation_class', 'annotation_type', 'neurotransmitter']].assign(
|
|
audit_source_group=labels).to_parquet(EXP / 'protocol/neuron-source-groups.parquet', index=False)
|
|
inventory = [dict(case=name, repeat=0, kind='fixture') for name in read(AG_MODEL / 'config.json')['fixtures']]
|
|
for row in read(AG / 'protocol/calibration-cases.json'):
|
|
inventory.append(dict(case=row['name'], repeat=0, kind='calibration'))
|
|
if row['seed'] == 51101:
|
|
inventory.append(dict(case=row['name'], repeat=1, kind='calibration'))
|
|
assert len(inventory) == len({(r['case'], r['repeat']) for r in inventory}) == 80
|
|
for row in inventory:
|
|
source = AG / 'gpu' / (row['case'] + '-r' + str(row['repeat']))
|
|
assert read(source / 'summary.json')['complete']
|
|
row['source'] = str(source.relative_to(ROOT))
|
|
save(EXP / 'protocol/inventory.json', inventory)
|
|
save(EXP / 'protocol/prepared-hashes.json', [dict(path=str(p.relative_to(EXP)), sha256=digest(p))
|
|
for p in sorted((EXP / 'protocol').iterdir()) if p.is_file() and p.name != 'prepared-hashes.json'])
|
|
print('REGISTERED fixed 80 existing records; no new brain simulation', flush=True)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|