diff --git a/rugnux_anomalous.py b/rugnux_anomalous.py index 49da8ef6..056a142f 100644 --- a/rugnux_anomalous.py +++ b/rugnux_anomalous.py @@ -98,6 +98,7 @@ if __name__ == "__main__" and not os.environ.get("RUGNUX_ANO_BOOTSTRAPPED"): import argparse import json import math +import re import shutil import statistics import datetime @@ -111,6 +112,12 @@ CCP4_SETUP_DEFAULT = "/opt/xtal/ccp4-9/bin/ccp4.setup-sh" # leading-letters rule gets them wrong. ANOM = {"S", "CL", "P", "CA", "K", "FE", "ZN", "SE", "BR", "CU", "MN", "NI", "CO", "I"} +# ANODE names its ranked peaks after the SFAC element it was given, so the labels read +# S1, S2, ... on a sulfur case but FE1, MN1, ZN1, ... as soon as the model carries a +# heavier scatterer. Matching only "S" silently drops the whole peak list on exactly +# those datasets, which then fail the gate as "no peaks" however strong they are. +PEAK_LABEL = re.compile(r"^[A-Za-z]{1,2}\d+$") + # ANODE is run with -s4.0, so its ranked peak list stops at ~4 sigma. An empty off-site # list therefore means "below 4", not "zero". FLOOR_MIN = 4.0 @@ -282,7 +289,7 @@ def parse_lsa(lsa, pdb, spag): atoms.append((f[3], float(f[0]))) except ValueError: pass - elif mode == "peaks" and len(f) == 8 and f[0][0] == "S" and f[0][1:].isdigit(): + elif mode == "peaks" and len(f) == 8 and PEAK_LABEL.match(f[0]): try: peaks.append({"xyz": tuple(float(v) for v in f[1:4]), "h": float(f[4]), "dist": float(f[6]), "near": f[7]})