ddimunzio/bot-detector
1
1import glob2import csv3import sys4from bot_detector_engine import analyze_file5 6files = glob.glob('cqww-cw/*.log') + glob.glob('cqww-ssb/*.log')7headers = ['file', 'callsign', 'mode', 'multi_tx', 'score', 'verdict', 'p_bot', 'p_suspicious', 'p_human', 'prior', 'log_lr', 'fatigue_flat', 'isfe_flag', 'bsiq_flag', 'cpd_flag']8writer = csv.DictWriter(sys.stdout, fieldnames=headers)9writer.writeheader()10 11results = []12for f in files:13 try:14 r = analyze_file(f)15 mode = 'CW' if 'cqww-cw' in f else 'SSB'16 17 # Determine isfe_flag, bsiq_flag, cpd_flag from metrics/artifacts18 # Adjusting to what might be available in result object based on previous turns19 isfe_f = 1 if r.metrics.get('isfe_detected') else 020 bsiq_f = 1 if r.metrics.get('bsiq_detected') else 021 cpd_f = 1 if r.metrics.get('cpd_detected') else 022 23 row = {24 'file': f,25 'callsign': r.callsign,26 'mode': mode,27 'multi_tx': r.multi_tx,28 'score': round(r.suspicion_score, 4),29 'verdict': r.verdict,30 'p_bot': round(r.bayes_p_bot, 4),31 'p_suspicious': round(r.bayes_p_suspicious, 4),32 'p_human': round(r.bayes_p_human, 4),33 'prior': round(r.bayes_prior, 4),34 'log_lr': round(r.log_likelihood_ratio, 4),35 'fatigue_flat': 1 if r.metrics.get('fatigue_penalty_applied') else 0,36 'isfe_flag': isfe_f,37 'bsiq_flag': bsiq_f,38 'cpd_flag': cpd_f39 }40 writer.writerow(row)41 results.append(row)42 except Exception as e:43 # sys.stderr.write(f'Error processing {f}: {e}\n')44 pass45 46# Summaries47print('\n--- Summaries ---')48by_mode = {}49for r in results:50 m = r['mode']51 if m not in by_mode: by_mode[m] = {'p_bot_sum': 0, 'count': 0, 'verdicts': {}}52 by_mode[m]['p_bot_sum'] += r['p_bot']53 by_mode[m]['count'] += 154 v = r['verdict']55 by_mode[m]['verdicts'][v] = by_mode[m]['verdicts'].get(v, 0) + 156 57for m, stats in by_mode.items():58 mean_p_bot = stats['p_bot_sum'] / stats['count'] if stats['count'] > 0 else 059 print(f'Mode: {m}, Mean P_Bot: {mean_p_bot:.4f}, Verdicts: {stats["verdicts"]}')60 