"""Orthogonal evidence axes. Never converts predicted dopamine to DAN identity.""" import numpy as np import pandas as pd def roles(meta, mapped_dan_ids=()): required=['neuron_idx','body_id','annotation_class','annotation_type','neurotransmitter','nt_ground_truth'] missing=set(required)-set(meta.columns) if missing:raise ValueError(f'Missing actual schema columns: {sorted(missing)}') out=meta[required].copy() cls=meta.annotation_class.fillna('');typ=meta.annotation_type.fillna('') nt=meta.neurotransmitter.fillna('').str.strip().str.lower() out['metadata_dopamine']=nt.eq('dopamine') out['annotation_DAN']=cls.eq('DAN') out['annotation_DPM']=typ.eq('DPM') out['has_frozen_MB_DAN_mapping']=meta.neuron_idx.isin(mapped_dan_ids) out['has_raw_ground_truth']=meta.nt_ground_truth.notna() & meta.nt_ground_truth.fillna('').ne('') out['identity_conflict']=out.annotation_DAN & out.annotation_DPM out['role_group']='other_annotation' out.loc[cls.isin(['ALPN','olfactory']),'role_group']='PN_olfactory_annotation' out.loc[cls.eq('Kenyon_Cell'),'role_group']='KC_annotation' out.loc[cls.eq('MBON'),'role_group']='MBON_annotation' out.loc[typ.eq('APL'),'role_group']='APL_annotation' other_dop=out.metadata_dopamine & ~out.annotation_DAN & ~out.annotation_DPM # Preserve separate evidence booleans even when the reporting group is disjoint. out.loc[other_dop & out.role_group.eq('other_annotation'),'role_group']='dopamine_metadata_role_unknown' out.loc[out.annotation_DAN,'role_group']='DAN_annotation' out.loc[out.annotation_DPM,'role_group']='DPM_annotation' out.loc[out.identity_conflict,'role_group']='identity_conflict_unknown' return out def self_test(): x=pd.DataFrame({'neuron_idx':np.arange(5,dtype=np.int32),'body_id':np.arange(5,dtype=np.uint64), 'annotation_class':[None,'DAN',None,'DAN',None],'annotation_type':['DPM','PAM15',None,'DPM','PAM-not-proof'], 'neurotransmitter':['dopamine']*5,'nt_ground_truth':[None]*5}) y=roles(x,[1]) assert y.annotation_DAN.tolist()==[False,True,False,True,False] assert y.role_group.tolist()==['DPM_annotation','DAN_annotation','dopamine_metadata_role_unknown','identity_conflict_unknown','dopamine_metadata_role_unknown'] assert not y.has_raw_ground_truth.any() and y.has_frozen_MB_DAN_mapping.tolist()==[False,True,False,False,False] try:roles(x.drop(columns='nt_ground_truth')) except ValueError:pass else:raise AssertionError('Missing schema must fail') return {'pass':True,'DPM_not_inferred_DAN':True,'PAM_name_not_identity_proof':True,'unknown_retained':True,'conflict_flagged':True,'schema_fail_closed':True}