"""Fixed descriptive ALPN-count comparisons; pure NumPy, no files or tuning. Column positions refer to the caller's fixed canonical 686-ALPN order. This module cannot assign body IDs or infer anatomical identities. Repeated runs are integrity evidence, never additional independent seeds in these metrics. """ from __future__ import annotations import itertools import numpy as np MODES = ('physiological', 'matched_energy') ODORS = tuple(range(6)) SEEDS = tuple(range(51101, 51106)) N_ALPN = 686 FIELDS = frozenset(('mode', 'odor_index', 'seed', 'counts', 'design_mask')) METRICS = ('cosine_distance', 'pearson_correlation', 'jaccard', 'euclidean_distance') def _require(condition, message): if not condition: raise ValueError(message) def _integer(value, name): _require(isinstance(value, (int, np.integer)) and not isinstance(value, (bool, np.bool_)), name + ' must be an integer, not a Boolean') return int(value) def _array(value, dtype, name): _require(isinstance(value, np.ndarray) and not np.ma.isMaskedArray(value), name + ' must be an unmasked NumPy array') _require(value.dtype == np.dtype(dtype) and value.shape == (N_ALPN,), name + ' must have dtype ' + np.dtype(dtype).name + ' and shape (686,)') return np.array(value, copy=True, order='C') def _pair_metrics(first, second): # Cast BEFORE subtraction/norm so int32 extrema do not overflow. x, y = first.astype(np.float64), second.astype(np.float64) active_x, active_y = first > 0, second > 0 intersection = int(np.count_nonzero(active_x & active_y)) union = int(np.count_nonzero(active_x | active_y)) result = dict(active_a=int(active_x.sum()), active_b=int(active_y.sum()), active_intersection=intersection, active_union=union) if not len(first): result.update({name: None for name in METRICS}) return result norm_x, norm_y = float(np.linalg.norm(x)), float(np.linalg.norm(y)) cosine = None if norm_x == 0 or norm_y == 0 else float(np.clip( np.dot(x, y) / (norm_x * norm_y), -1., 1.)) # A constant or one-channel vector has undefined Pearson correlation; # equality does not turn it into evidence of shared structure. correlation = None if bool(np.all(x == x[0]) or np.all(y == y[0])) else float( np.clip(np.corrcoef(x, y)[0, 1], -1., 1.)) result.update(cosine_distance=None if cosine is None else float(1. - cosine), pearson_correlation=correlation, jaccard=None if union == 0 else float(intersection / union), euclidean_distance=float(np.linalg.norm(x - y))) _require(all(value is None or np.isfinite(value) for value in result.values()), 'A structure metric became nonfinite') return result def _summary(rows): result = {} for name in METRICS: values = np.asarray([row[name] for row in rows if row[name] is not None], np.float64) result[name] = dict(mean=None if not len(values) else float(values.mean()), variance_ddof0=None if not len(values) else float(values.var(ddof=0)), valid_comparisons=int(len(values)), undefined_comparisons=int(len(rows) - len(values))) return result def _view(mode, records, positions): arrays = {(odor, seed): records[(mode, odor, seed)]['counts'][positions] for odor in ODORS for seed in SEEDS} within, between, pairs = [], [], [] for odor in ODORS: for first_seed, second_seed in itertools.combinations(SEEDS, 2): within.append(dict(odor_index=odor, seed_a=first_seed, seed_b=second_seed, **_pair_metrics(arrays[(odor, first_seed)], arrays[(odor, second_seed)]))) for first_odor, second_odor in itertools.combinations(ODORS, 2): pair_between = [] for seed in SEEDS: row = dict(odor_index_a=first_odor, odor_index_b=second_odor, seed=seed, **_pair_metrics(arrays[(first_odor, seed)], arrays[(second_odor, seed)])) pair_between.append(row) between.append(row) # Original pair-specific comparison: 10 within-seed pairs for each # member odor, not a baseline pooled across all six odors. pair_within = [row for row in within if row['odor_index'] in (first_odor, second_odor)] within_summary, between_summary = _summary(pair_within), _summary(pair_between) differences = {name: None if (within_summary[name]['mean'] is None or between_summary[name]['mean'] is None) else float(between_summary[name]['mean'] - within_summary[name]['mean']) for name in METRICS} pairs.append(dict(odor_index_a=first_odor, odor_index_b=second_odor, within_comparison_count=len(pair_within), between_comparison_count=len(pair_between), within=within_summary, between=between_summary, mean_between_minus_within=differences, within_comparisons=pair_within, between_comparisons=pair_between)) _require(len(within) == 60 and len(between) == 75 and len(pairs) == 15 and all(row['within_comparison_count'] == 20 and row['between_comparison_count'] == 5 for row in pairs), 'Internal fixed comparison inventory changed') return dict(dimensions=int(len(positions)), applicable=bool(len(positions)), column_positions=[int(value) for value in positions], within_comparison_count=len(within), between_comparison_count=len(between), pair_count=len(pairs), within=_summary(within), between=_summary(between), within_comparisons=within, between_comparisons=between, pairs=pairs) def aggregate_structure(records): """Describe precisely 60 fixed CAL records, without selecting results. Each record has exactly mode, odor_index, seed, counts:int32[686] and design_mask:bool[686]. There are two named modes, six odors (0..5), five seeds (51101..51105), and no repeat records. Every odor's design mask must be identical across seeds AND modes. No caller-owned array is modified. Undefined cosine (zero norm), Pearson (constant vector), or Jaccard (empty active union) is null with explicit valid/undefined counts. An empty common-nondesign population is nonapplicable, with every metric null. """ _require(isinstance(records, list) and len(records) == 60, 'Exactly 60 base CAL records are required; technical repeats must be excluded') indexed, masks = {}, {} for position, record in enumerate(records): _require(isinstance(record, dict) and set(record) == FIELDS, 'Record schema must contain exactly ' + ', '.join(sorted(FIELDS))) mode = record['mode'] _require(isinstance(mode, str) and mode in MODES, 'Unexpected CAL mode') odor = _integer(record['odor_index'], 'odor_index') seed = _integer(record['seed'], 'seed') _require(odor in ODORS and seed in SEEDS, 'Odor index or seed outside the fixed CAL inventory') key = mode, odor, seed _require(key not in indexed, 'Duplicate CAL identity: ' + str(key)) counts = _array(record['counts'], np.int32, 'counts') design = _array(record['design_mask'], np.bool_, 'design_mask') _require(bool(np.all(counts >= 0)), 'Spike counts must be nonnegative') if odor in masks: _require(np.array_equal(design, masks[odor]), 'An odor design mask changed across seed or mode: ' + str(odor)) else: masks[odor] = design.copy() indexed[key] = dict(counts=counts, design_mask=design) expected = set(itertools.product(MODES, ODORS, SEEDS)) _require(set(indexed) == expected, 'Incomplete fixed CAL identity set') union = np.logical_or.reduce([masks[odor] for odor in ODORS]) primary = np.arange(N_ALPN, dtype=np.int32) common = np.flatnonzero(~union).astype(np.int32) return dict(schema='phase4ai-alpn-structure-v1', record_count=60, ALPN_dimensions=N_ALPN, design=dict(identical_across_seeds_and_modes=True, design_neuron_count_by_odor={str(odor): int(masks[odor].sum()) for odor in ODORS}, design_union_count=int(union.sum()), common_non_design_count=int(len(common)), common_non_design_column_positions=[int(value) for value in common], common_non_design_definition='Fixed complement of the union of all six CAL odor design masks; same columns in all modes/seeds'), modes={mode: dict(trials=30, fixed_686=_view(mode, indexed, primary), common_non_design=_view(mode, indexed, common)) for mode in MODES}, protocol=dict(odor_indices=list(ODORS), seeds=list(SEEDS), variance_ddof=0, within='All 10 distinct seed pairs within each of six odors: 60 comparisons per mode', between='Same-seed pairs for each of 15 odor pairs: 75 comparisons per mode', pair_baseline='Only each odor pair: 10+10 within comparisons and five same-seed between comparisons', counts='Original nonnegative int32 spike counts; no normalization, fitting or resampling', undefined_cosine='null if either vector has zero norm', undefined_Pearson='null if either vector is constant, including dimension one', undefined_Jaccard='null if active union is empty', empty_population='All metrics null, applicable=false; no fabricated zero distance', clipping='Only cosine/correlation numerical roundoff is clipped to their mathematical [-1,1] range', technical_repeats_included=False, population_columns='Caller-supplied fixed canonical ALPN order; positions are not neuron_idx'), decision_gate_applied=False, learning_claimed=False, absence_of_encoding_claimed=False, limitations=['Descriptive CAL structure only, not a held-out or learning result', 'Shared activity can coexist with odor-specific information', 'Active-set Jaccard can saturate even when spike-count patterns differ', 'Valid metric counts vary when a metric is undefined; null is not zero similarity', 'No KC sparsity gate is transferred to the ALPN population'])