{
 "kind": "independent_check",
 "checker_version": "0.1.0",
 "origin": {
  "source": "family-pilot-v37"
 },
 "checked": 316,
 "passed": 316,
 "failed": [],
 "by_family": {
  "named_bond_angle": {
   "pass": 4
  },
  "backbone_torsion": {
   "pass": 7
  },
  "force_path_derivative": {
   "pass": 5
  },
  "kinematic_extinction": {
   "pass": 8
  },
  "conformer_target_selection": {
   "pass": 4
  },
  "extent_choice_v2": {
   "pass": 15
  },
  "stereo_relationship": {
   "pass": 8
  },
  "stereo_property_inference": {
   "pass": 4
  },
  "stereo_design_selection": {
   "pass": 3
  },
  "named_bond_distance": {
   "pass": 8
  },
  "coordination_shell": {
   "pass": 22
  },
  "first_diffraction_peak": {
   "pass": 22
  },
  "fret_efficiency": {
   "pass": 8
  },
  "guinier_intensity": {
   "pass": 11
  },
  "assembly_extent": {
   "pass": 13
  },
  "assembly_rg": {
   "pass": 12
  },
  "capsid_architecture": {
   "pass": 12
  },
  "debye_intensity": {
   "pass": 8
  },
  "scattering_q_design": {
   "pass": 12
  },
  "superlattice_shell": {
   "pass": 1
  },
  "superlattice_metric": {
   "pass": 3
  },
  "superlattice_saxs": {
   "pass": 3
  },
  "superlattice_design": {
   "pass": 3
  },
  "opal_geometry": {
   "pass": 3
  },
  "opal_bragg": {
   "pass": 4
  },
  "opal_design": {
   "pass": 3
  },
  "moire_geometry": {
   "pass": 3
  },
  "moire_inference": {
   "pass": 4
  },
  "moire_design": {
   "pass": 3
  },
  "secondary_structure": {
   "pass": 6
  },
  "binding_evidence_choice": {
   "pass": 3
  },
  "binding_design_choice": {
   "pass": 2
  },
  "qdot_optics": {
   "pass": 3
  },
  "qdot_design": {
   "pass": 2
  },
  "diffraction_design": {
   "pass": 6
  },
  "disulfide_design": {
   "pass": 7
  },
  "fret_design": {
   "pass": 7
  },
  "vortex_geometry": {
   "pass": 3
  },
  "vortex_inference": {
   "pass": 4
  },
  "vortex_design": {
   "pass": 3
  },
  "cholesteric_geometry": {
   "pass": 3
  },
  "cholesteric_optics": {
   "pass": 4
  },
  "cholesteric_design": {
   "pass": 3
  },
  "rotational_line": {
   "pass": 3
  },
  "isotopologue_design": {
   "pass": 3
  },
  "hbond_geometry": {
   "pass": 3
  },
  "hbond_criteria": {
   "pass": 2
  },
  "evidence_quantity": {
   "pass": 12
  },
  "evidence_elimination": {
   "pass": 15
  },
  "design_choice": {
   "pass": 6
  }
 },
 "checker_sha256": {
  "checkers/__init__.py": "b424176da0e26fafcb424be028ec0e1df44a2abe887e8c37002ebe9d6db464d6",
  "checkers/cells.py": "0f3d1c3fab442486b16887b96f88a0c9c972876000204a38f5995da93ddf4ee3",
  "checkers/common.py": "fbc9f4eb287114ac4720d27edc1ea40e25f80da0e1cff6bdee06fbdca2b73aed",
  "checkers/design_extra.py": "0d42baeb6018399150e5e6f85a3b805b533388ba28d7198deb1cd22f4ba2a02d",
  "checkers/evidence.py": "577fb0a912b4b122cdbbc22390bf575ff1d036f522ababed9a3a40b22e128ee9",
  "checkers/families.py": "1b44f1eab578c983fa0c433d5ba82b86888a12e5a6033b928d69ee0ced4ef88c",
  "checkers/hbonds.py": "31403a45307cefac4c850430d1e6db93eaadf15c898a0d15822e7941a386ed0f",
  "checkers/hostguest.py": "d6c8fb867e6d313c84cce0e6e3fa51e3497a11e4a0e9f826095a804dd5a46654",
  "checkers/mesoscale.py": "55a3a182757904d2fc9680a142005bb6015d5926687a73e3ac51f71da824342f",
  "checkers/migrated.py": "f1cf6f20bca7ad81fd3b5ee5c6749084a090a32dd40b0a394768995a6e3a42eb",
  "checkers/moire.py": "ceee9cd8039687cea219647978e575bb01c97d8c964b596fafb8df7b5d750a50",
  "checkers/paper_design.py": "5931be583eb5bcc1707b4e277198e3ddb015b06f61f48d2e17e2be96d5aefa04",
  "checkers/quantum_dot.py": "d1cdad3a661f98dddac3c5d6bedfcd68e9bb6cb223a03624526e7d96cf3af63f",
  "checkers/rotational.py": "2ba544a31a644ef654de95c16143919963ca2afab72b5864101a1f54916f47d2",
  "checkers/stereo.py": "70f02daf0cae0c92a6c79fc118cc08334330e93287e688931a653bd927489625",
  "checkers/superlattice.py": "c03a5a7bd5ced3e525f1c4d5b2c9a27971d3bc5af7a4c95115a13984f6e24fee",
  "verify_all.py": "cb635bbfaefededbe0bb69f3685fb8530b10db754c970493fbd85b80cb19921b"
 },
 "model_calls": 0,
 "scope": "Checks input→output, all four options, key agreement, answer-key leakage and source hashes. It does not judge scientific meaning or source interpretation; those remain sampled human/model review.",
 "results": [
  {
   "id": "FA-ANG-BCD",
   "family": "named_bond_angle",
   "checker_version": "0.1.0",
   "recomputed": "116.0251189438",
   "rounded": "116.03",
   "label": "D",
   "nearest_distractor_gap": "4.3251189438",
   "parameters": {
    "atoms": [
     [
      "C4",
      "4"
     ],
     [
      "O3",
      "45"
     ],
     [
      "C37",
      "37"
     ]
    ],
    "vertex": "O3"
   },
   "method": "law of cosines from three Decimal distances",
   "status": "pass"
  },
  {
   "id": "FA-ANG-WP6",
   "family": "named_bond_angle",
   "checker_version": "0.1.0",
   "recomputed": "119.9446786883",
   "rounded": "119.94",
   "label": "C",
   "nearest_distractor_gap": "2.3146786883",
   "parameters": {
    "atoms": [
     [
      "C3",
      "3"
     ],
     [
      "C1",
      "1"
     ],
     [
      "C4",
      "4"
     ]
    ],
    "vertex": "C1"
   },
   "method": "law of cosines from three Decimal distances",
   "status": "pass"
  },
  {
   "id": "FA-ANG-DMBCD",
   "family": "named_bond_angle",
   "checker_version": "0.1.0",
   "recomputed": "107.6182710356",
   "rounded": "107.62",
   "label": "B",
   "nearest_distractor_gap": "1.8517289644",
   "parameters": {
    "atoms": [
     [
      "C3",
      "3"
     ],
     [
      "O2",
      "44"
     ],
     [
      "CH3-C45",
      "45"
     ]
    ],
    "vertex": "O2"
   },
   "method": "law of cosines from three Decimal distances",
   "status": "pass"
  },
  {
   "id": "FA-TOR-1CRN-G20",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "106.2572069382",
   "rounded": "106.3",
   "label": "A",
   "nearest_distractor_gap": "32.5572069382",
   "parameters": {
    "atoms": "C(19)–N(20)–CA(20)–C(20)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "FA-TOR-1UBQ-V26",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "-46.4088436388",
   "rounded": "-46.4",
   "label": "B",
   "nearest_distractor_gap": "11.9911563612",
   "parameters": {
    "atoms": "N(26)–CA(26)–C(26)–N(27)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "FA-TOR-6LYZ-T43",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "-143.6458783156",
   "rounded": "-143.6",
   "label": "C",
   "nearest_distractor_gap": "12.9541216844",
   "parameters": {
    "atoms": "C(42)–N(43)–CA(43)–C(43)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "FA-FP-QM7X-7001",
   "family": "force_path_derivative",
   "checker_version": "0.1.0",
   "recomputed": "1.8479097251",
   "rounded": "1.8479",
   "label": "D",
   "nearest_distractor_gap": "0.9239097251",
   "parameters": {
    "direction": "A_to_B",
    "atoms": 14
   },
   "method": "Decimal atom-by-atom projection",
   "status": "pass"
  },
  {
   "id": "FA-FP-QM7X-7002",
   "family": "force_path_derivative",
   "checker_version": "0.1.0",
   "recomputed": "-0.4352795772",
   "rounded": "-0.4353",
   "label": "A",
   "nearest_distractor_gap": "0.0981795772",
   "parameters": {
    "direction": "B_to_A",
    "atoms": 11
   },
   "method": "Decimal atom-by-atom projection",
   "status": "pass"
  },
  {
   "id": "FA-FP-QM7X-7035",
   "family": "force_path_derivative",
   "checker_version": "0.1.0",
   "recomputed": "5.5319173445",
   "rounded": "5.5319",
   "label": "B",
   "nearest_distractor_gap": "0.5067826555",
   "parameters": {
    "direction": "A_to_B",
    "atoms": 17
   },
   "method": "Decimal atom-by-atom projection",
   "status": "pass"
  },
  {
   "id": "FA-EXT-NACL",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "(3 1 0)",
   "parameters": {
    "weights": {
     "Cl": 17,
     "Na": 11
    },
    "a_A": 5.64056,
    "atoms": 8
   },
   "options": {
    "A": 1.0,
    "B": 0.21428571,
    "C": 0.0,
    "D": 1.0
   },
   "weakest_nonzero": 0.214286,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-EXT-DIAMOND",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "(2 2 2)",
   "parameters": {
    "weights": {
     "C": 6
    },
    "a_A": 3.56679,
    "atoms": 8
   },
   "options": {
    "A": 0.70710678,
    "B": 0.70710678,
    "C": 1.0,
    "D": 0.0
   },
   "weakest_nonzero": 0.707107,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-EXT-SALEM2",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "(1 1 1)",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1,
     "N": 7,
     "Zn": 30
    },
    "a_A": 16.8303,
    "atoms": 204
   },
   "options": {
    "A": 0.0,
    "B": 0.14600426,
    "C": 0.16411769,
    "D": 0.2762629
   },
   "weakest_nonzero": 0.146004,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-EXT-MOF5",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "(1 1 0)",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1,
     "O": 8,
     "Zn": 30
    },
    "a_A": 25.8247,
    "atoms": 424
   },
   "options": {
    "A": 0.28045276,
    "B": 0.0,
    "C": 0.61651269,
    "D": 0.08730021
   },
   "weakest_nonzero": 0.0873,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-CONF-7050-max_dipole",
   "family": "conformer_target_selection",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "D",
   "parameters": {
    "goal": "max_dipole",
    "atoms": 16
   },
   "options": {
    "A": 0.57848,
    "B": 0.722212,
    "C": 0.638431,
    "D": 1.043318
   },
   "lead": 0.321106,
   "policy_margin": 0.1,
   "method": "own bond graph, handedness and distance-matrix checks; property matched by coordinates",
   "status": "pass"
  },
  {
   "id": "FA-CONF-7206-min_energy",
   "family": "conformer_target_selection",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "A",
   "parameters": {
    "goal": "min_energy",
    "atoms": 13
   },
   "options": {
    "A": -20175.79801,
    "B": -20175.647611,
    "C": -20175.736603,
    "D": -20175.650674
   },
   "lead": 0.061407,
   "policy_margin": 0.0434,
   "method": "own bond graph, handedness and distance-matrix checks; property matched by coordinates",
   "status": "pass"
  },
  {
   "id": "FA-CONF-7095-min_energy",
   "family": "conformer_target_selection",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "B",
   "parameters": {
    "goal": "min_energy",
    "atoms": 15
   },
   "options": {
    "A": -18085.093111,
    "B": -18085.278387,
    "C": -18085.032646,
    "D": -18085.069543
   },
   "lead": 0.185276,
   "policy_margin": 0.0434,
   "method": "own bond graph, handedness and distance-matrix checks; property matched by coordinates",
   "status": "pass"
  },
  {
   "id": "FA-CONF-7032-max_dipole",
   "family": "conformer_target_selection",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "C",
   "parameters": {
    "goal": "max_dipole",
    "atoms": 17
   },
   "options": {
    "A": 1.123048,
    "B": 1.115202,
    "C": 1.301605,
    "D": 1.119083
   },
   "lead": 0.178557,
   "policy_margin": 0.1,
   "method": "own bond graph, handedness and distance-matrix checks; property matched by coordinates",
   "status": "pass"
  },
  {
   "id": "FC-QNP007",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "10.0002886395",
   "rounded": "10.0003",
   "label": "D",
   "nearest_distractor_gap": "0.9800886395",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 41
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-QNP008",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "11.8783581855",
   "rounded": "11.8784",
   "label": "A",
   "nearest_distractor_gap": "0.6755418145",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 57
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-QNP009",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "14.0869752409",
   "rounded": "14.0870",
   "label": "B",
   "nearest_distractor_gap": "1.3401247591",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 64
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-QNP010",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "4.2466757170",
   "rounded": "4.2467",
   "label": "C",
   "nearest_distractor_gap": "0.2635757170",
   "parameters": {
    "measure": "equal_weight_rg",
    "atoms": 48
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-QNP011",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "4.6156086064",
   "rounded": "4.6156",
   "label": "D",
   "nearest_distractor_gap": "0.2279086064",
   "parameters": {
    "measure": "equal_weight_rg",
    "atoms": 70
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-MNP006",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "17.8512288891",
   "rounded": "17.8512",
   "label": "A",
   "nearest_distractor_gap": "0.9655711109",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 12
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-MNP007",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "23.9458638075",
   "rounded": "23.9459",
   "label": "B",
   "nearest_distractor_gap": "2.3128361925",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 32
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-MNP010",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "30.6102126568",
   "rounded": "30.6102",
   "label": "C",
   "nearest_distractor_gap": "6.1558126568",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 424
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-CNP007",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "19.5697811945",
   "rounded": "19.5698",
   "label": "D",
   "nearest_distractor_gap": "0.7934811945",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 132
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-CNP008",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "19.2645768965",
   "rounded": "19.2646",
   "label": "A",
   "nearest_distractor_gap": "1.5857231035",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 132
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-CNP009",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "28.7192483537",
   "rounded": "28.7192",
   "label": "B",
   "nearest_distractor_gap": "0.0857516463",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 264
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-CNP011",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "8.2616830454",
   "rounded": "8.2617",
   "label": "C",
   "nearest_distractor_gap": "0.5069830454",
   "parameters": {
    "measure": "equal_weight_rg",
    "atoms": 264
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7029-SAME",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "same",
   "parameters": {
    "same_dataset_molecule": true
   },
   "facts": {
    "centres": [],
    "inverted": [],
    "switched": []
   },
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7052-SAME",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "same",
   "parameters": {
    "same_dataset_molecule": true
   },
   "facts": {
    "centres": [
     1
    ],
    "inverted": [],
    "switched": []
   },
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7208-ENAN",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "enantiomer",
   "parameters": {
    "same_dataset_molecule": true
   },
   "facts": {
    "centres": [
     3,
     4
    ],
    "inverted": [
     3,
     4
    ],
    "switched": []
   },
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7111-ENAN",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "enantiomer",
   "parameters": {
    "same_dataset_molecule": true
   },
   "facts": {
    "centres": [
     4
    ],
    "inverted": [
     4
    ],
    "switched": []
   },
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7110-DIAS",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "diastereomer",
   "parameters": {
    "same_dataset_molecule": true
   },
   "facts": {
    "centres": [
     4,
     5
    ],
    "inverted": [
     4
    ],
    "switched": []
   },
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7043-DIAS",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "diastereomer",
   "parameters": {
    "same_dataset_molecule": true
   },
   "facts": {
    "centres": [],
    "inverted": [],
    "switched": [
     [
      1,
      2
     ]
    ]
   },
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7082-CONS",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "constitutional",
   "parameters": {
    "same_dataset_molecule": false
   },
   "facts": {},
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SREL-7033-CONS",
   "family": "stereo_relationship",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "constitutional",
   "parameters": {
    "same_dataset_molecule": false
   },
   "facts": {},
   "method": "own bond graph, stereo elements and colour-refinement invariant",
   "status": "pass"
  },
  {
   "id": "FA-SPROP-7082",
   "family": "stereo_property_inference",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": {
    "delta_energy_eV": 0.110025,
    "delta_dipole_eA": 0.246827
   },
   "facts": {
    "centres": [],
    "inverted": [],
    "switched": [
     [
      1,
      2
     ]
    ]
   },
   "method": "structures matched to dataset by distance matrix and handedness; signs and margins recomputed",
   "status": "pass"
  },
  {
   "id": "FA-SPROP-7089",
   "family": "stereo_property_inference",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": {
    "delta_energy_eV": -0.153327,
    "delta_dipole_eA": -0.302921
   },
   "facts": {
    "centres": [],
    "inverted": [],
    "switched": [
     [
      1,
      2
     ]
    ]
   },
   "method": "structures matched to dataset by distance matrix and handedness; signs and margins recomputed",
   "status": "pass"
  },
  {
   "id": "FA-SPROP-7110",
   "family": "stereo_property_inference",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": {
    "delta_energy_eV": 0.080082,
    "delta_dipole_eA": 0.411569
   },
   "facts": {
    "centres": [
     4,
     5
    ],
    "inverted": [
     4
    ],
    "switched": []
   },
   "method": "structures matched to dataset by distance matrix and handedness; signs and margins recomputed",
   "status": "pass"
  },
  {
   "id": "FA-SPROP-7114",
   "family": "stereo_property_inference",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": {
    "delta_energy_eV": -0.09323,
    "delta_dipole_eA": -0.219906
   },
   "facts": {
    "centres": [],
    "inverted": [],
    "switched": [
     [
      1,
      2
     ]
    ]
   },
   "method": "structures matched to dataset by distance matrix and handedness; signs and margins recomputed",
   "status": "pass"
  },
  {
   "id": "FA-SDES-7029",
   "family": "stereo_design_selection",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "C",
   "options": {
    "A": {
     "relation": "constitutional",
     "delta_energy_eV": -0.091096,
     "mirror_of_dataset": false
    },
    "B": {
     "relation": "same",
     "delta_energy_eV": 0.0,
     "mirror_of_dataset": false
    },
    "C": {
     "relation": "diastereomer",
     "delta_energy_eV": -0.059006,
     "mirror_of_dataset": false
    },
    "D": {
     "relation": "same",
     "delta_energy_eV": -0.05441,
     "mirror_of_dataset": false
    }
   },
   "method": "own relationship classification per candidate; energies by dataset matching or reflection symmetry",
   "status": "pass"
  },
  {
   "id": "FA-SDES-7033",
   "family": "stereo_design_selection",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "D",
   "options": {
    "A": {
     "relation": "same",
     "delta_energy_eV": -0.053962,
     "mirror_of_dataset": false
    },
    "B": {
     "relation": "constitutional",
     "delta_energy_eV": -0.149146,
     "mirror_of_dataset": false
    },
    "C": {
     "relation": "same",
     "delta_energy_eV": 0.0,
     "mirror_of_dataset": false
    },
    "D": {
     "relation": "diastereomer",
     "delta_energy_eV": -0.171284,
     "mirror_of_dataset": false
    }
   },
   "method": "own relationship classification per candidate; energies by dataset matching or reflection symmetry",
   "status": "pass"
  },
  {
   "id": "FA-SDES-7110",
   "family": "stereo_design_selection",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "A",
   "options": {
    "A": {
     "relation": "diastereomer",
     "delta_energy_eV": -0.176277,
     "mirror_of_dataset": false
    },
    "B": {
     "relation": "constitutional",
     "delta_energy_eV": 0.005973,
     "mirror_of_dataset": false
    },
    "C": {
     "relation": "same",
     "delta_energy_eV": -0.096195,
     "mirror_of_dataset": false
    },
    "D": {
     "relation": "enantiomer",
     "delta_energy_eV": 0.0,
     "mirror_of_dataset": true
    }
   },
   "method": "own relationship classification per candidate; energies by dataset matching or reflection symmetry",
   "status": "pass"
  },
  {
   "id": "FA-DIST-7035-SO",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "1.4615652691",
   "rounded": "1.462",
   "label": "B",
   "nearest_distractor_gap": "0.0215652691",
   "parameters": {
    "atoms": [
     [
      "S3",
      "3"
     ],
     [
      "O4",
      "4"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-DIST-7070-CCl",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "1.7371752009",
   "rounded": "1.737",
   "label": "B",
   "nearest_distractor_gap": "0.0428247991",
   "parameters": {
    "atoms": [
     [
      "Cl1",
      "1"
     ],
     [
      "C2",
      "2"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-DIST-7002-NN",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "1.1872477578",
   "rounded": "1.187",
   "label": "A",
   "nearest_distractor_gap": "0.1887522422",
   "parameters": {
    "atoms": [
     [
      "N5",
      "5"
     ],
     [
      "N6",
      "6"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-DIST-7122-CN",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "1.4013389197",
   "rounded": "1.401",
   "label": "C",
   "nearest_distractor_gap": "0.0653389197",
   "parameters": {
    "atoms": [
     [
      "C5",
      "5"
     ],
     [
      "N7",
      "7"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-DIST-6LYZ-SS",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "2.0306976634",
   "rounded": "2.031",
   "label": "B",
   "nearest_distractor_gap": "0.0693023366",
   "parameters": {
    "atoms": [
     [
      "SG",
      "Cys",
      "6"
     ],
     [
      "SG",
      "Cys",
      "127"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-ANG-7040-OSO",
   "family": "named_bond_angle",
   "checker_version": "0.1.0",
   "recomputed": "121.9601734637",
   "rounded": "121.96",
   "label": "D",
   "nearest_distractor_gap": "10.9501734637",
   "parameters": {
    "atoms": [
     [
      "O4",
      "4"
     ],
     [
      "S3",
      "3"
     ],
     [
      "O5",
      "5"
     ]
    ],
    "vertex": "S3"
   },
   "method": "law of cosines from three Decimal distances",
   "status": "pass"
  },
  {
   "id": "FA-COORD-MGO",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "6 at 2.1085 Å",
   "parameters": {
    "partner": "O",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-COORD-CSCL",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "8 at 3.5706 Å",
   "parameters": {
    "partner": "Cl",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-COORD-SALEM2-ZN",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "4 at 5.9504 Å",
   "parameters": {
    "partner": "Zn",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-COORD-MOF5-NODE",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "6 at 12.9123 Å",
   "parameters": {
    "partner": "O",
    "mu4_node": true
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-NACL",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "27.3644317294",
   "rounded": "27.36",
   "label": "D",
   "nearest_distractor_gap": "5.0944317294",
   "parameters": {
    "weights": {
     "Cl": 17,
     "Na": 11
    },
    "wavelength_A": 1.5406,
    "reflection": [
     1,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-CSCL",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "21.5356856961",
   "rounded": "21.54",
   "label": "A",
   "nearest_distractor_gap": "9.1043143039",
   "parameters": {
    "weights": {
     "Cl": 17,
     "Cs": 55
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     0,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-MGO",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "36.8889819180",
   "rounded": "36.89",
   "label": "B",
   "nearest_distractor_gap": "5.9710180820",
   "parameters": {
    "weights": {
     "Mg": 12,
     "O": 8
    },
    "wavelength_A": 1.5406,
    "reflection": [
     1,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-SALEM2",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "7.4223150084",
   "rounded": "7.42",
   "label": "C",
   "nearest_distractor_gap": "1.6676849916",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1,
     "N": 7,
     "Zn": 30
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-MOF5",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "5.9228571183",
   "rounded": "5.92",
   "label": "D",
   "nearest_distractor_gap": "1.0828571183",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1,
     "O": 8,
     "Zn": 30
    },
    "wavelength_A": 1.5406,
    "reflection": [
     1,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-FRET-1EHZ",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.2455710301",
   "rounded": "0.246",
   "label": "A",
   "nearest_distractor_gap": "0.0914289699",
   "parameters": {
    "sites": [
     [
      "C1'",
      "A",
      "76"
     ],
     [
      "C1'",
      "A",
      "35"
     ]
    ],
    "R0_nm": 6.0,
    "r_nm": 7.234215712155672
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "FA-FRET-1UBQ",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.7997785261",
   "rounded": "0.800",
   "label": "B",
   "nearest_distractor_gap": "0.1292214739",
   "parameters": {
    "sites": [
     [
      "NZ",
      "Lys",
      "48"
     ],
     [
      "NZ",
      "Lys",
      "63"
     ]
    ],
    "R0_nm": 2.5,
    "r_nm": 1.9847089484355132
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "FA-FRET-6LYZ",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.5751210546",
   "rounded": "0.575",
   "label": "C",
   "nearest_distractor_gap": "0.0751210546",
   "parameters": {
    "sites": [
     [
      "CA",
      "Lys",
      "1"
     ],
     [
      "CA",
      "Leu",
      "129"
     ]
    ],
    "R0_nm": 2.2,
    "r_nm": 2.0917366445133574
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "FA-GUIN-6LYZ",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7913164591",
   "rounded": "0.791",
   "label": "B",
   "nearest_distractor_gap": "0.0986835409",
   "parameters": {
    "q_per_nm": 0.6,
    "rg_nm": 1.3965950155693867,
    "atoms": 1001
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-GUIN-1EHZ",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7655007634",
   "rounded": "0.766",
   "label": "B",
   "nearest_distractor_gap": "0.0814992366",
   "parameters": {
    "q_per_nm": 0.4,
    "rg_nm": 2.2384079160659227,
    "atoms": 1329
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-GUIN-1BNA",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7543782426",
   "rounded": "0.754",
   "label": "C",
   "nearest_distractor_gap": "0.0363782426",
   "parameters": {
    "q_per_nm": 0.7,
    "rg_nm": 1.3136521502257867,
    "atoms": 486
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1AON",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "20.3005200342",
   "rounded": "20.30",
   "label": "C",
   "nearest_distractor_gap": "7.1394799658",
   "parameters": {
    "points": 8015
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1AON",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "6.8409055341",
   "rounded": "6.84",
   "label": "B",
   "nearest_distractor_gap": "1.9609055341",
   "parameters": {
    "points": 8015
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-GUIN-1AON",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7039943743",
   "rounded": "0.704",
   "label": "D",
   "nearest_distractor_gap": "0.0549943743",
   "parameters": {
    "q_per_nm": 0.15,
    "rg_nm": 6.840905534067554,
    "atoms": 8015
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1KX5",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "16.8743479655",
   "rounded": "16.87",
   "label": "D",
   "nearest_distractor_gap": "6.5843479655",
   "parameters": {
    "points": 1266
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1KX5",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "3.8996125118",
   "rounded": "3.90",
   "label": "C",
   "nearest_distractor_gap": "0.3296125118",
   "parameters": {
    "points": 1266
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-GUIN-1KX5",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7284676677",
   "rounded": "0.728",
   "label": "B",
   "nearest_distractor_gap": "0.1255323323",
   "parameters": {
    "q_per_nm": 0.25,
    "rg_nm": 3.899612511795535,
    "atoms": 1266
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1A34",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "17.2978423701",
   "rounded": "17.30",
   "label": "B",
   "nearest_distractor_gap": "1.6521576299",
   "parameters": {
    "points": 8820
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1A34",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "7.3396913470",
   "rounded": "7.34",
   "label": "A",
   "nearest_distractor_gap": "2.1403086530",
   "parameters": {
    "points": 8820
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-GUIN-1A34",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7033099056",
   "rounded": "0.703",
   "label": "B",
   "nearest_distractor_gap": "0.1356900944",
   "parameters": {
    "q_per_nm": 0.14,
    "rg_nm": 7.339691346977608,
    "atoms": 8820
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-ASM-CAPS-1A34",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "12.0000000000",
   "rounded": "12",
   "label": "C",
   "nearest_distractor_gap": "2.0000000000",
   "parameters": {
    "component": "CP",
    "copies": 60,
    "T": 1
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-6CGR",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "113.6987631669",
   "rounded": "113.70",
   "label": "B",
   "nearest_distractor_gap": "11.4712368331",
   "parameters": {
    "points": 960
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-6CGR",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "53.7367008097",
   "rounded": "53.74",
   "label": "B",
   "nearest_distractor_gap": "22.7167008097",
   "parameters": {
    "points": 960
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-T-6CGR",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "16.0000000000",
   "rounded": "16",
   "label": "B",
   "nearest_distractor_gap": "3.0000000000",
   "parameters": {
    "component": "VP5",
    "copies": 960,
    "T": 16
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-CAPS-6CGR",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "162.0000000000",
   "rounded": "162",
   "label": "C",
   "nearest_distractor_gap": "2.0000000000",
   "parameters": {
    "component": "VP5",
    "copies": 960,
    "T": 16
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-HEX-6CGR",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "150.0000000000",
   "rounded": "150",
   "label": "A",
   "nearest_distractor_gap": "10.0000000000",
   "parameters": {
    "component": "VP5",
    "copies": 960,
    "T": 16
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-7ARQ",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "33.8710835463",
   "rounded": "33.87",
   "label": "C",
   "nearest_distractor_gap": "4.2510835463",
   "parameters": {
    "points": 2689
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-7ARQ",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "9.3858424101",
   "rounded": "9.39",
   "label": "C",
   "nearest_distractor_gap": "0.6858424101",
   "parameters": {
    "points": 2689
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-7ARQ-SCAF",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "32.4205110578",
   "rounded": "32.42",
   "label": "D",
   "nearest_distractor_gap": "3.8405110578",
   "parameters": {
    "points": 1317
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-7ARQ-SCAF",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "9.2231599614",
   "rounded": "9.22",
   "label": "C",
   "nearest_distractor_gap": "0.6631599614",
   "parameters": {
    "points": 1317
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-GUIN-7ARQ",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.6551759974",
   "rounded": "0.655",
   "label": "C",
   "nearest_distractor_gap": "0.1568240026",
   "parameters": {
    "q_per_nm": 0.12,
    "rg_nm": 9.38584241011186,
    "atoms": 2689
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-DEB-7ARQ-018",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.4177611665",
   "rounded": "0.418",
   "label": "A",
   "nearest_distractor_gap": "0.1332388335",
   "parameters": {
    "q_per_nm": 0.18,
    "points": 2689
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-DEB-7ARQ-030",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.1373954701",
   "rounded": "0.137",
   "label": "B",
   "nearest_distractor_gap": "0.1346045299",
   "parameters": {
    "q_per_nm": 0.3,
    "points": 2689
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-7ARQ-050",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.1586070535",
   "rounded": "0.159",
   "label": "D",
   "nearest_distractor_gap": "0.0086070535",
   "parameters": {
    "target": 0.5,
    "rg_nm": 9.385842410111861,
    "points": 2689
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-QDES-7ARQ-030",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.2166895890",
   "rounded": "0.217",
   "label": "A",
   "nearest_distractor_gap": "0.0333104110",
   "parameters": {
    "target": 0.3,
    "rg_nm": 9.385842410111861,
    "points": 2689
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-QDES-7ARQ-SCAF-020",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.2624504287",
   "rounded": "0.262",
   "label": "B",
   "nearest_distractor_gap": "0.0384504287",
   "parameters": {
    "target": 0.2,
    "rg_nm": 9.22315996138367,
    "points": 1317
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-DEB-6CGR",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.2565440072",
   "rounded": "0.257",
   "label": "C",
   "nearest_distractor_gap": "0.0514559928",
   "parameters": {
    "q_per_nm": 0.035,
    "points": 960
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-6CGR",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.0258983463",
   "rounded": "0.0259",
   "label": "C",
   "nearest_distractor_gap": "0.0103983463",
   "parameters": {
    "target": 0.5,
    "rg_nm": 53.73670080974997,
    "points": 960
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-SL-SHELL-X",
   "family": "superlattice_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "count": 12,
    "distance_nm": 28.14284997620958
   },
   "method": "shells around the centroid particle",
   "status": "pass"
  },
  {
   "id": "FA-SL-EDGE-26",
   "family": "superlattice_metric",
   "checker_version": "0.1.0",
   "recomputed": "56.9999996510",
   "rounded": "57.00",
   "label": "C",
   "nearest_distractor_gap": "12.8100003490",
   "parameters": {
    "nn_nm": 40.30508611838722,
    "primitive_volume_nm3": 46298.249149557756
   },
   "method": "primitive basis from coordinates; reciprocal lattice",
   "status": "pass"
  },
  {
   "id": "FA-SL-EDGE-52",
   "family": "superlattice_metric",
   "checker_version": "0.1.0",
   "recomputed": "76.5999997260",
   "rounded": "76.60",
   "label": "D",
   "nearest_distractor_gap": "22.4399997260",
   "parameters": {
    "nn_nm": 54.16437890654102,
    "primitive_volume_nm3": 112363.77279414433
   },
   "method": "primitive basis from coordinates; reciprocal lattice",
   "status": "pass"
  },
  {
   "id": "FA-SL-D111-39",
   "family": "superlattice_metric",
   "checker_version": "0.1.0",
   "recomputed": "38.9711432283",
   "rounded": "38.97",
   "label": "A",
   "nearest_distractor_gap": "2.3688567717",
   "parameters": {
    "nn_nm": 47.72970740142258,
    "primitive_volume_nm3": 76886.7169711259
   },
   "method": "primitive basis from coordinates; reciprocal lattice",
   "status": "pass"
  },
  {
   "id": "FA-SL-QSTAR-X",
   "family": "superlattice_saxs",
   "checker_version": "0.1.0",
   "recomputed": "0.2734370868",
   "rounded": "0.2734",
   "label": "C",
   "nearest_distractor_gap": "0.0422629132",
   "parameters": {
    "nn_nm": 28.1428496325025,
    "primitive_volume_nm3": 15761.198142785659
   },
   "method": "primitive basis from coordinates; reciprocal lattice",
   "status": "pass"
  },
  {
   "id": "FA-SL-Q200-13",
   "family": "superlattice_saxs",
   "checker_version": "0.1.0",
   "recomputed": "0.2737771401",
   "rounded": "0.2738",
   "label": "D",
   "nearest_distractor_gap": "0.0366771401",
   "parameters": {
    "nn_nm": 32.45620068840472,
    "primitive_volume_nm3": 24175.643698373853
   },
   "method": "primitive basis from coordinates; reciprocal lattice",
   "status": "pass"
  },
  {
   "id": "FA-SL-GOLD-52",
   "family": "superlattice_saxs",
   "checker_version": "0.1.0",
   "recomputed": "0.5091948277",
   "rounded": "0.509",
   "label": "A",
   "nearest_distractor_gap": "0.9308051723",
   "parameters": {
    "nn_nm": 54.16437890654102,
    "primitive_volume_nm3": 112363.77279414433
   },
   "method": "primitive basis from coordinates; reciprocal lattice",
   "status": "pass"
  },
  {
   "id": "FA-SL-DES-QSTAR",
   "family": "superlattice_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "Au-FCC-13-linker.xyz": {
     "nn": 32.45620068840472,
     "q": 0.23709795655218102,
     "volume": 24175.643698373853
    },
    "Au-FCC-26-linker.xyz": {
     "nn": 40.30508611838722,
     "q": 0.19092624877377856,
     "volume": 46298.249149557756
    },
    "Au-FCC-39-linker.xyz": {
     "nn": 47.72970740142258,
     "q": 0.16122660991419932,
     "volume": 76886.7169711259
    },
    "Au-FCC-52-linker.xyz": {
     "nn": 54.16437890654102,
     "q": 0.14207305724073513,
     "volume": 112363.77279414433
    }
   },
   "method": "per-file lattice analysis; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-SL-DES-NN",
   "family": "superlattice_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "Au-FCC-13-linker.xyz": {
     "nn": 32.45620068840472,
     "q": 0.23709795655218102,
     "volume": 24175.643698373853
    },
    "Au-FCC-26-linker.xyz": {
     "nn": 40.30508611838722,
     "q": 0.19092624877377856,
     "volume": 46298.249149557756
    },
    "Au-FCC-39-linker.xyz": {
     "nn": 47.72970740142258,
     "q": 0.16122660991419932,
     "volume": 76886.7169711259
    },
    "Au-FCC-52-linker.xyz": {
     "nn": 54.16437890654102,
     "q": 0.14207305724073513,
     "volume": 112363.77279414433
    }
   },
   "method": "per-file lattice analysis; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-SL-DES-GOLD",
   "family": "superlattice_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "Au-FCC-X-linker.xyz": {
     "nn": 28.1428496325025,
     "q": 0.273437086833002,
     "volume": 15761.198142785659
    },
    "Au-FCC-13-linker.xyz": {
     "nn": 32.45620068840472,
     "q": 0.23709795655218102,
     "volume": 24175.643698373853
    },
    "Au-FCC-26-linker.xyz": {
     "nn": 40.30508611838722,
     "q": 0.19092624877377856,
     "volume": 46298.249149557756
    },
    "Au-FCC-39-linker.xyz": {
     "nn": 47.72970740142258,
     "q": 0.16122660991419932,
     "volume": 76886.7169711259
    }
   },
   "method": "per-file lattice analysis; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-OP-DIAM-S8",
   "family": "opal_geometry",
   "checker_version": "0.1.0",
   "recomputed": "208.8499995106",
   "rounded": "208.8",
   "label": "D",
   "nearest_distractor_gap": "38.3499995106",
   "parameters": {
    "nn_nm": 208.84999951057978,
    "d111_nm": 170.52531144199162
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-D111-S2",
   "family": "opal_geometry",
   "checker_version": "0.1.0",
   "recomputed": "301.5975073101",
   "rounded": "301.6",
   "label": "A",
   "nearest_distractor_gap": "18.3024926899",
   "parameters": {
    "nn_nm": 369.37999960598574,
    "d111_nm": 301.5975073100996
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-EDGE-SIO2",
   "family": "opal_geometry",
   "checker_version": "0.1.0",
   "recomputed": "376.1808074129",
   "rounded": "376.2",
   "label": "B",
   "nearest_distractor_gap": "84.5191925871",
   "parameters": {
    "nn_nm": 265.99999941891997,
    "d111_nm": 217.1880907290671
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-PEAK-S3",
   "family": "opal_bragg",
   "checker_version": "0.1.0",
   "recomputed": "814.9671174055",
   "rounded": "815.0",
   "label": "D",
   "nearest_distractor_gap": "12.8671174055",
   "parameters": {
    "nn_nm": 341.82999950213997,
    "d111_nm": 279.10302639767207
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-PEAK-S7-WATER",
   "family": "opal_bragg",
   "checker_version": "0.1.0",
   "recomputed": "560.3782964899",
   "rounded": "560.4",
   "label": "A",
   "nearest_distractor_gap": "23.2217035101",
   "parameters": {
    "nn_nm": 224.75999954644922,
    "d111_nm": 183.51577151858308
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-PEAK-SIO2-30",
   "family": "opal_bragg",
   "checker_version": "0.1.0",
   "recomputed": "544.7049604015",
   "rounded": "544.7",
   "label": "B",
   "nearest_distractor_gap": "36.9049604015",
   "parameters": {
    "nn_nm": 265.99999941891997,
    "d111_nm": 217.1880907290671
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-ANGLE-SIO2",
   "family": "opal_bragg",
   "checker_version": "0.1.0",
   "recomputed": "44.8581367145",
   "rounded": "44.9",
   "label": "C",
   "nearest_distractor_gap": "13.3581367145",
   "parameters": {
    "nn_nm": 265.99999941891997,
    "d111_nm": 217.1880907290671
   },
   "method": "reciprocal lattice; Bragg-Snell",
   "status": "pass"
  },
  {
   "id": "FA-OP-DES-540",
   "family": "opal_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "peaks_nm": {
     "opal-PS-S5.xyz": 616.5836705254787,
     "opal-PS-S6.xyz": 593.9105954818115,
     "opal-PS-S7.xyz": 535.8570319432915,
     "opal-PS-S8.xyz": 497.92552661404727
    }
   },
   "method": "per-file reciprocal lattice; Bragg-Snell; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-OP-DES-820",
   "family": "opal_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "peaks_nm": {
     "opal-PS-S2.xyz": 880.6498962438974,
     "opal-PS-S3.xyz": 814.9671174055134,
     "opal-PS-S4.xyz": 779.5389474041781,
     "opal-PS-S5.xyz": 616.5836705254787
    }
   },
   "method": "per-file reciprocal lattice; Bragg-Snell; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-OP-DES-BELOW700",
   "family": "opal_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "peaks_nm": {
     "opal-PS-S4.xyz": 779.5389474041781,
     "opal-PS-S5.xyz": 616.5836705254787,
     "opal-PS-S6.xyz": 593.9105954818115,
     "opal-PS-S7.xyz": 535.8570319432915
    }
   },
   "method": "per-file reciprocal lattice; Bragg-Snell; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-MO-PERIOD-K079",
   "family": "moire_geometry",
   "checker_version": "0.1.0",
   "recomputed": "17.8416114386",
   "rounded": "17.84",
   "label": "B",
   "nearest_distractor_gap": "2.3916114386",
   "parameters": {
    "period_nm": 17.841611438599063,
    "cell_area_nm2": 275.675889603675
   },
   "method": "primitive moire cell from AA sites",
   "status": "pass"
  },
  {
   "id": "FA-MO-AREA-M2",
   "family": "moire_geometry",
   "checker_version": "0.1.0",
   "recomputed": "156.0557096156",
   "rounded": "156.1",
   "label": "B",
   "nearest_distractor_gap": "24.1442903844",
   "parameters": {
    "period_nm": 13.423770279921882,
    "cell_area_nm2": 156.055709615601
   },
   "method": "primitive moire cell from AA sites",
   "status": "pass"
  },
  {
   "id": "FA-MO-PERIOD-D1",
   "family": "moire_geometry",
   "checker_version": "0.1.0",
   "recomputed": "13.0508981792",
   "rounded": "13.05",
   "label": "C",
   "nearest_distractor_gap": "1.7508981792",
   "parameters": {
    "period_nm": 13.050898179197668,
    "cell_area_nm2": 147.50660238681402
   },
   "method": "primitive moire cell from AA sites",
   "status": "pass"
  },
  {
   "id": "FA-MO-ATOMS-K110",
   "family": "moire_inference",
   "checker_version": "0.1.0",
   "recomputed": "12.8134914421",
   "rounded": "12.81",
   "label": "A",
   "nearest_distractor_gap": "4.6365085579",
   "parameters": {
    "twist_deg": 1.1000106305725517,
    "a_nm": 0.2459999750396836
   },
   "method": "six-fold phase average per layer",
   "status": "pass"
  },
  {
   "id": "FA-MO-NFULL-M1",
   "family": "moire_inference",
   "checker_version": "0.1.0",
   "recomputed": "3.1283478930",
   "rounded": "3.128",
   "label": "B",
   "nearest_distractor_gap": "2.3463478930",
   "parameters": {
    "period_nm": 12.150863839214436,
    "cell_area_nm2": 127.863017054843
   },
   "method": "primitive moire cell from AA sites",
   "status": "pass"
  },
  {
   "id": "FA-MO-NHALF-K079",
   "family": "moire_inference",
   "checker_version": "0.1.0",
   "recomputed": "0.7254896331",
   "rounded": "0.725",
   "label": "C",
   "nearest_distractor_gap": "0.0974896331",
   "parameters": {
    "period_nm": 17.841611438599063,
    "cell_area_nm2": 275.675889603675
   },
   "method": "primitive moire cell from AA sites",
   "status": "pass"
  },
  {
   "id": "FA-MO-TWIST-D1",
   "family": "moire_inference",
   "checker_version": "0.1.0",
   "recomputed": "1.0800000301",
   "rounded": "1.080",
   "label": "D",
   "nearest_distractor_gap": "0.4560000301",
   "parameters": {
    "period_nm": 13.050898179197668,
    "cell_area_nm2": 147.50660238681402
   },
   "method": "primitive moire cell from AA sites",
   "status": "pass"
  },
  {
   "id": "FA-MO-DES-HALF",
   "family": "moire_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "TBG-M2-AA-map.txt": 1.2815936084148625,
    "TBG-D1-AA-map.txt": 1.3558715119444613,
    "TBG-K110-AA-map.txt": 1.4065524030122591,
    "TBG-M1-AA-map.txt": 1.56417394651509
   },
   "method": "per-file primitive moire cell; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-MO-DES-PERIOD",
   "family": "moire_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "TBG-K079-AA-map.txt": 17.841611438599063,
    "TBG-M2-AA-map.txt": 13.423770279921882,
    "TBG-D1-AA-map.txt": 13.050898179197668,
    "TBG-M1-AA-map.txt": 12.150863839214436
   },
   "method": "per-file primitive moire cell; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-MO-DES-FULL",
   "family": "moire_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "TBG-K079-AA-map.txt": 1.4509792661776095,
    "TBG-D1-AA-map.txt": 2.7117430238889226,
    "TBG-K110-AA-map.txt": 2.8131048060245183,
    "TBG-M1-AA-map.txt": 3.12834789303018
   },
   "method": "per-file primitive moire cell; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-6NCL",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "172.6441469207",
   "rounded": "172.64",
   "label": "A",
   "nearest_distractor_gap": "1.7158530793",
   "parameters": {
    "points": 5040
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-T-6NCL",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "169.0000000000",
   "rounded": "169",
   "label": "D",
   "nearest_distractor_gap": "1.0000000000",
   "parameters": {
    "component": "Vp54",
    "copies": 5040,
    "T": 169
   },
   "method": "count copies; trimeric capsomers = 10(T-1)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-6NCL",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.0179603612",
   "rounded": "0.0180",
   "label": "D",
   "nearest_distractor_gap": "0.0012603612",
   "parameters": {
    "target": 0.5,
    "rg_nm": 77.5005991581565,
    "points": 5040
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-SS-1UBQ-43",
   "family": "secondary_structure",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "phi": -103.55814450046749,
    "psi": 130.24087804410922,
    "distances": {
     "right-handed α-helix": 183.25389400821257,
     "β-strand": 16.443619872146183,
     "polyproline II": 32.14652855626,
     "left-handed α-helix": 180.85342557714318
    },
    "record": "SHEET"
   },
   "method": "acos dihedrals; nearest reference; HELIX/SHEET evidence",
   "status": "pass"
  },
  {
   "id": "FA-SS-6LYZ-90",
   "family": "secondary_structure",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "phi": -62.69998414778826,
    "psi": -37.11612772240395,
    "distances": {
     "right-handed α-helix": 11.409677930812475,
     "β-strand": 176.66661246991336,
     "polyproline II": 178.30861562593316,
     "left-handed α-helix": 146.2997236770888
    },
    "record": "HELIX"
   },
   "method": "acos dihedrals; nearest reference; HELIX/SHEET evidence",
   "status": "pass"
  },
  {
   "id": "FA-SS-1CRN-34",
   "family": "secondary_structure",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "phi": -111.5631605009207,
    "psi": 129.5883632802384,
    "distances": {
     "right-handed α-helix": 184.82583296131168,
     "β-strand": 8.446875488740242,
     "polyproline II": 39.678498613203494,
     "left-handed α-helix": 187.70822258859036
    },
    "record": "SHEET"
   },
   "method": "acos dihedrals; nearest reference; HELIX/SHEET evidence",
   "status": "pass"
  },
  {
   "id": "FA-HG-EV1",
   "family": "binding_evidence_choice",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "measured_DG": {
     "A": -6.97,
     "B": -6.43,
     "C": -10.84,
     "D": -7.99
    }
   },
   "method": "measured ITC ΔG from the SAMPL9 table",
   "status": "pass"
  },
  {
   "id": "FA-HG-EV2",
   "family": "binding_evidence_choice",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "measured_DG": {
     "A": -7.77,
     "B": -5.4,
     "C": -6.23,
     "D": -9.83
    }
   },
   "method": "measured ITC ΔG from the SAMPL9 table",
   "status": "pass"
  },
  {
   "id": "FA-HG-EV3",
   "family": "binding_evidence_choice",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "measured_DG": {
     "A": -7.91,
     "B": -5.96,
     "C": -6.17,
     "D": -5.4
    }
   },
   "method": "measured ITC ΔG from the SAMPL9 table",
   "status": "pass"
  },
  {
   "id": "FA-HG-DES1",
   "family": "binding_design_choice",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "reference": "G7",
    "improvement": {
     "A": -0.54,
     "B": 3.4699999999999998,
     "C": 1.0200000000000005,
     "D": 0.9400000000000004
    }
   },
   "method": "measured ITC ΔG; design threshold",
   "status": "pass"
  },
  {
   "id": "FA-HG-DES2",
   "family": "binding_design_choice",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "reference": "G13",
    "improvement": {
     "A": -0.4800000000000004,
     "B": 1.3599999999999994,
     "C": 2.369999999999999,
     "D": -3.0700000000000003
    }
   },
   "method": "measured ITC ΔG; design threshold",
   "status": "pass"
  },
  {
   "id": "FA-QD-PEAK-C",
   "family": "qdot_optics",
   "checker_version": "0.1.0",
   "recomputed": "578.0705790406",
   "rounded": "578.1",
   "label": "C",
   "nearest_distractor_gap": "32.8705790406",
   "parameters": {
    "D_nm": 3.7572097820057904
   },
   "method": "Decimal Dmax; quartic roots",
   "status": "pass"
  },
  {
   "id": "FA-QD-EPS-E",
   "family": "qdot_optics",
   "checker_version": "0.1.0",
   "recomputed": "4.1321853733",
   "rounded": "4.132",
   "label": "B",
   "nearest_distractor_gap": "2.0401853733",
   "parameters": {
    "D_nm": 4.983665614986624
   },
   "method": "Decimal Dmax; quartic roots",
   "status": "pass"
  },
  {
   "id": "FA-QD-CONC-B",
   "family": "qdot_optics",
   "checker_version": "0.1.0",
   "recomputed": "1.8261244293",
   "rounded": "1.826",
   "label": "B",
   "nearest_distractor_gap": "1.3621244293",
   "parameters": {
    "D_nm": 3.2847593239079176
   },
   "method": "Decimal Dmax; quartic roots",
   "status": "pass"
  },
  {
   "id": "FA-QD-DES-590",
   "family": "qdot_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "D_nm": {
     "CdSe-QD-B.xyz": 3.2847593239079176,
     "CdSe-QD-C.xyz": 3.7572097820057904,
     "CdSe-QD-D.xyz": 4.264145050440944,
     "CdSe-QD-E.xyz": 4.983665614986624
    },
    "peak_nm": {
     "CdSe-QD-B.xyz": 561.0613166209203,
     "CdSe-QD-C.xyz": 578.070579040603,
     "CdSe-QD-D.xyz": 592.3662054210863,
     "CdSe-QD-E.xyz": 608.5183340301639
    }
   },
   "method": "per-file Dmax; quartic roots; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-QD-DES-565",
   "family": "qdot_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "D_nm": {
     "CdSe-QD-A.xyz": 2.798626426302732,
     "CdSe-QD-B.xyz": 3.2847593239079176,
     "CdSe-QD-C.xyz": 3.7572097820057904,
     "CdSe-QD-D.xyz": 4.264145050440944
    },
    "peak_nm": {
     "CdSe-QD-A.xyz": 536.6496681944732,
     "CdSe-QD-B.xyz": 561.0613166209203,
     "CdSe-QD-C.xyz": 578.070579040603,
     "CdSe-QD-D.xyz": 592.3662054210863
    }
   },
   "method": "per-file Dmax; quartic roots; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-XD-CRYSTAL-CU",
   "family": "diffraction_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "values": {
     "NaCl-cell.txt": 27.3637,
     "MgO-cell.txt": 36.888,
     "CsCl-cell.txt": 21.5351,
     "diamond-cell.txt": 43.9314
    }
   },
   "method": "own structure-factor search; Bragg law",
   "status": "pass"
  },
  {
   "id": "FA-XD-CRYSTAL-MO",
   "family": "diffraction_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "values": {
     "NaCl-cell.txt": 12.5041,
     "MgO-cell.txt": 16.7516,
     "CsCl-cell.txt": 9.8691,
     "diamond-cell.txt": 19.8338
    }
   },
   "method": "own structure-factor search; Bragg law",
   "status": "pass"
  },
  {
   "id": "FA-XD-ANODE-NACL",
   "family": "diffraction_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "values": {
     "A": 31.8847,
     "B": 41.1643,
     "C": 27.3637,
     "D": 12.5041
    }
   },
   "method": "own structure-factor search; Bragg law",
   "status": "pass"
  },
  {
   "id": "FA-XD-ANODE-MOF5",
   "family": "diffraction_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "values": {
     "A": 8.8075,
     "B": 6.8788,
     "C": 5.9227,
     "D": 2.726
    }
   },
   "method": "own structure-factor search; Bragg law",
   "status": "pass"
  },
  {
   "id": "FA-XD-ANODE-SALEM2",
   "family": "diffraction_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "values": {
     "A": 8.621,
     "B": 7.4221,
     "C": 11.0407,
     "D": 3.4154
    }
   },
   "method": "own structure-factor search; Bragg law",
   "status": "pass"
  },
  {
   "id": "FA-XD-WAVE-MOF5",
   "family": "diffraction_design",
   "checker_version": "0.1.0",
   "recomputed": "1.3007211890",
   "rounded": "1.3007",
   "label": "C",
   "nearest_distractor_gap": "0.1742211890",
   "parameters": {
    "d_A": 14.90989749674133
   },
   "method": "own structure-factor search; Bragg law",
   "status": "pass"
  },
  {
   "id": "FA-DS-1UBQ-A",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "FA-DS-1UBQ-B",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "FA-DS-6LYZ",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "FA-FD-1EHZ",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "efficiency": {
     "A": 0.7966,
     "B": 0.4995,
     "C": 0.2282,
     "D": 0.1524
    },
    "R0_nm": 5.4
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "FA-FD-1UBQ",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "efficiency": {
     "A": 0.9357,
     "B": 0.5006,
     "C": 0.7509,
     "D": 0.2141
    },
    "R0_nm": 2.5
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "FA-FD-6LYZ",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "efficiency": {
     "A": 0.097,
     "B": 0.4994,
     "C": 0.7492,
     "D": 0.2503
    },
    "R0_nm": 3.0
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "FA-QDES-1AON",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.2072122808",
   "rounded": "0.207",
   "label": "A",
   "nearest_distractor_gap": "0.0577877192",
   "parameters": {
    "target": 0.5,
    "rg_nm": 6.840905534067554,
    "points": 8015
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-QDES-1KX5",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.3762867955",
   "rounded": "0.376",
   "label": "B",
   "nearest_distractor_gap": "0.1632867955",
   "parameters": {
    "target": 0.5,
    "rg_nm": 3.8996125117955347,
    "points": 1266
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-QDES-1A34",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.1899244737",
   "rounded": "0.190",
   "label": "C",
   "nearest_distractor_gap": "0.0769244737",
   "parameters": {
    "target": 0.5,
    "rg_nm": 7.339691346977607,
    "points": 8820
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-VX-SPACING-561",
   "family": "vortex_geometry",
   "checker_version": "0.1.0",
   "recomputed": "652.3956747029",
   "rounded": "652.4",
   "label": "C",
   "nearest_distractor_gap": "45.2956747029",
   "parameters": {
    "spacing_nm": 652.3956747029436,
    "cell_nm2": 368597.8334546518
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-DENSITY-1173",
   "family": "vortex_geometry",
   "checker_version": "0.1.0",
   "recomputed": "5.6726027708",
   "rounded": "5.673",
   "label": "C",
   "nearest_distractor_gap": "0.5823972292",
   "parameters": {
    "spacing_nm": 451.17341136977757,
    "cell_nm2": 176285.92030924358
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-SPACING-BSCCO",
   "family": "vortex_geometry",
   "checker_version": "0.1.0",
   "recomputed": "854.9999997559",
   "rounded": "855.0",
   "label": "B",
   "nearest_distractor_gap": "114.4999997559",
   "parameters": {
    "spacing_nm": 854.9999997558529,
    "cell_nm2": 633086.2207076936
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-FIELD-BSCCO",
   "family": "vortex_inference",
   "checker_version": "0.1.0",
   "recomputed": "3.2662217757",
   "rounded": "3.266",
   "label": "C",
   "nearest_distractor_gap": "0.4372217757",
   "parameters": {
    "spacing_nm": 854.9999997558529,
    "cell_nm2": 633086.2207076936
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-FIELD-508",
   "family": "vortex_inference",
   "checker_version": "0.1.0",
   "recomputed": "5.0799168506",
   "rounded": "5.080",
   "label": "D",
   "nearest_distractor_gap": "0.6809168506",
   "parameters": {
    "spacing_nm": 685.5839593326479,
    "cell_nm2": 407053.90675097005
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-FLUX-1887",
   "family": "vortex_inference",
   "checker_version": "0.1.0",
   "recomputed": "2.0678338477",
   "rounded": "2.068",
   "label": "B",
   "nearest_distractor_gap": "0.3201661523",
   "parameters": {
    "spacing_nm": 355.7185829359448,
    "cell_nm2": 109583.13978406825
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-SANS-1173",
   "family": "vortex_inference",
   "checker_version": "0.1.0",
   "recomputed": "16.0807292173",
   "rounded": "16.08",
   "label": "C",
   "nearest_distractor_gap": "2.1507292173",
   "parameters": {
    "spacing_nm": 451.17341136977757,
    "cell_nm2": 176285.92030924358
   },
   "method": "primitive cell from vortex centres",
   "status": "pass"
  },
  {
   "id": "FA-VX-DES-SPACING",
   "family": "vortex_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "vortex-MgB2-508G.txt": {
     "spacing_nm": 685.5839593326479
    },
    "vortex-MgB2-561G.txt": {
     "spacing_nm": 652.3956747029436
    },
    "vortex-MgB2-1173G.txt": {
     "spacing_nm": 451.17341136977757
    },
    "vortex-MgB2-1887G.txt": {
     "spacing_nm": 355.7185829359448
    }
   },
   "method": "primitive cells; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-VX-DES-SANS",
   "family": "vortex_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "vortex-MgB2-508G.txt": {
     "spacing_nm": 685.5839593326479
    },
    "vortex-MgB2-561G.txt": {
     "spacing_nm": 652.3956747029436
    },
    "vortex-MgB2-1173G.txt": {
     "spacing_nm": 451.17341136977757
    },
    "vortex-MgB2-1887G.txt": {
     "spacing_nm": 355.7185829359448
    }
   },
   "method": "primitive cells; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-VX-DES-DENSITY",
   "family": "vortex_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "vortex-MgB2-508G.txt": {
     "spacing_nm": 685.5839593326479
    },
    "vortex-MgB2-561G.txt": {
     "spacing_nm": 652.3956747029436
    },
    "vortex-MgB2-1173G.txt": {
     "spacing_nm": 451.17341136977757
    },
    "vortex-MgB2-1887G.txt": {
     "spacing_nm": 355.7185829359448
    }
   },
   "method": "primitive cells; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-CH-PITCH-R5011",
   "family": "cholesteric_geometry",
   "checker_version": "0.1.0",
   "recomputed": "355.0505947157",
   "rounded": "355.05",
   "label": "B",
   "nearest_distractor_gap": "177.5205947157",
   "parameters": {
    "pitch_nm": 355.05059471572673,
    "hand": 1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-HAND-S5011",
   "family": "cholesteric_geometry",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "pitch_nm": 361.9581938394363,
    "hand": -1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-PITCH-LRCD",
   "family": "cholesteric_geometry",
   "checker_version": "0.1.0",
   "recomputed": "418.7500000110",
   "rounded": "418.75",
   "label": "B",
   "nearest_distractor_gap": "209.3800000110",
   "parameters": {
    "pitch_nm": 418.75000001095526,
    "hand": -1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-LAMBDA-R5011",
   "family": "cholesteric_optics",
   "checker_version": "0.1.0",
   "recomputed": "592.7214628184",
   "rounded": "592.7",
   "label": "D",
   "nearest_distractor_gap": "42.9214628184",
   "parameters": {
    "pitch_nm": 355.05059471572673,
    "hand": 1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-BAND-R5011",
   "family": "cholesteric_optics",
   "checker_version": "0.1.0",
   "recomputed": "85.9222439212",
   "rounded": "85.9",
   "label": "C",
   "nearest_distractor_gap": "34.4222439212",
   "parameters": {
    "pitch_nm": 355.05059471572673,
    "hand": 1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-HTP-S5011",
   "family": "cholesteric_optics",
   "checker_version": "0.1.0",
   "recomputed": "107.4999999968",
   "rounded": "107.5",
   "label": "C",
   "nearest_distractor_gap": "53.6999999968",
   "parameters": {
    "pitch_nm": 361.9581938394363,
    "hand": -1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-LAMBDA-RRCD",
   "family": "cholesteric_optics",
   "checker_version": "0.1.0",
   "recomputed": "603.0000000094",
   "rounded": "603.0",
   "label": "C",
   "nearest_distractor_gap": "37.7000000094",
   "parameters": {
    "pitch_nm": 376.87500000587767,
    "hand": 1
   },
   "method": "projected angle fit",
   "status": "pass"
  },
  {
   "id": "FA-CH-DES-550",
   "family": "cholesteric_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "clc-E44-R5011-2.20wt.txt": {
     "reflection_nm": 705.88,
     "hand": 1
    },
    "clc-E44-R5011-2.62wt.txt": {
     "reflection_nm": 592.72,
     "hand": 1
    },
    "clc-E44-R5011-2.90wt.txt": {
     "reflection_nm": 535.49,
     "hand": 1
    },
    "clc-E44-R5011-3.40wt.txt": {
     "reflection_nm": 456.74,
     "hand": 1
    }
   },
   "method": "projected angle fit per file; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-CH-DES-LEFT600",
   "family": "cholesteric_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "clc-E44-R5011-2.62wt.txt": {
     "reflection_nm": 592.72,
     "hand": 1
    },
    "clc-E44-S5011-2.57wt.txt": {
     "reflection_nm": 604.25,
     "hand": -1
    },
    "clc-LRCD-coating.txt": {
     "reflection_nm": 670.0,
     "hand": -1
    },
    "clc-RRCD-coating.txt": {
     "reflection_nm": 603.0,
     "hand": 1
    }
   },
   "method": "projected angle fit per file; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-CH-DES-BELOW620",
   "family": "cholesteric_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "clc-E44-R5011-2.20wt.txt": {
     "reflection_nm": 705.88,
     "hand": 1
    },
    "clc-E44-R5011-2.40wt.txt": {
     "reflection_nm": 647.05,
     "hand": 1
    },
    "clc-E44-R5011-2.62wt.txt": {
     "reflection_nm": 592.72,
     "hand": 1
    },
    "clc-E44-R5011-3.00wt.txt": {
     "reflection_nm": 517.64,
     "hand": 1
    }
   },
   "method": "projected angle fit per file; goal rule",
   "status": "pass"
  },
  {
   "id": "FA-COORD-RUTILE",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "4 at 1.9472 Å",
   "parameters": {
    "partner": "O",
    "cell": {
     "a": 4.593,
     "b": 4.593,
     "c": 2.959,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 6
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-ZNO",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "3 at 1.9736 Å",
   "parameters": {
    "partner": "O",
    "cell": {
     "a": 3.2494,
     "b": 3.2494,
     "c": 5.2054,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 4
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-QUARTZ",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "2 at 1.6054 Å",
   "parameters": {
    "partner": "O",
    "cell": {
     "a": 4.91239,
     "b": 4.91239,
     "c": 5.40385,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 9
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-RUTILE",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "27.4403473029",
   "rounded": "27.44",
   "label": "A",
   "nearest_distractor_gap": "8.6396526971",
   "parameters": {
    "weights": {
     "O": 8,
     "Ti": 22
    },
    "wavelength_A": 1.5406,
    "reflection": [
     -1,
     -1,
     0
    ],
    "cell": {
     "a": 4.593,
     "b": 4.593,
     "c": 2.959,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 6
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-ZNO",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "31.7729667934",
   "rounded": "31.77",
   "label": "B",
   "nearest_distractor_gap": "2.6570332066",
   "parameters": {
    "weights": {
     "O": 8,
     "Zn": 30
    },
    "wavelength_A": 1.5406,
    "reflection": [
     -1,
     0,
     0
    ],
    "cell": {
     "a": 3.2494,
     "b": 3.2494,
     "c": 5.2054,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 4
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-QUARTZ",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "20.8636915644",
   "rounded": "20.86",
   "label": "C",
   "nearest_distractor_gap": "2.8236915644",
   "parameters": {
    "weights": {
     "O": 8,
     "Si": 14
    },
    "wavelength_A": 1.5406,
    "reflection": [
     -1,
     0,
     0
    ],
    "cell": {
     "a": 4.91239,
     "b": 4.91239,
     "c": 5.40385,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 9
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-EXT-RUTILE",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "(0 1 0)",
   "parameters": {
    "weights": {
     "O": 8,
     "Ti": 22
    },
    "cell": {
     "a": 4.593,
     "b": 4.593,
     "c": 2.959,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "atoms": 6
   },
   "options": {
    "A": 0.43607199,
    "B": 0.17159748,
    "C": 0.0,
    "D": 0.25284822
   },
   "weakest_nonzero": 0.171597,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-EXT-BROOKITE",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "(0 1 3)",
   "parameters": {
    "weights": {
     "O": 8,
     "Ti": 22
    },
    "cell": {
     "a": 9.174,
     "b": 5.449,
     "c": 5.138,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "atoms": 24
   },
   "options": {
    "A": 0.354586,
    "B": 0.24506763,
    "C": 0.31224007,
    "D": 0.0
   },
   "weakest_nonzero": 0.245068,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-EXT-ZNO",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "(2 2 1)",
   "parameters": {
    "weights": {
     "O": 8,
     "Zn": 30
    },
    "cell": {
     "a": 3.2494,
     "b": 3.2494,
     "c": 5.2054,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "atoms": 4
   },
   "options": {
    "A": 0.0,
    "B": 1.0,
    "C": 1.0,
    "D": 0.49999998
   },
   "weakest_nonzero": 0.5,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1RYP",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "19.1380792247",
   "rounded": "19.14",
   "label": "B",
   "nearest_distractor_gap": "0.9519207753",
   "parameters": {
    "points": 6386
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1RYP",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "5.9693736168",
   "rounded": "5.97",
   "label": "A",
   "nearest_distractor_gap": "1.4406263832",
   "parameters": {
    "points": 6386
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1STM",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "17.0682867564",
   "rounded": "17.07",
   "label": "C",
   "nearest_distractor_gap": "0.7882867564",
   "parameters": {
    "points": 8460
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1STM",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "6.9976747649",
   "rounded": "7.00",
   "label": "B",
   "nearest_distractor_gap": "0.3876747649",
   "parameters": {
    "points": 8460
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-2BUK",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "19.4377477710",
   "rounded": "19.44",
   "label": "D",
   "nearest_distractor_gap": "9.3077477710",
   "parameters": {
    "points": 11040
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-2BUK",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "7.8454029783",
   "rounded": "7.85",
   "label": "C",
   "nearest_distractor_gap": "0.3154029783",
   "parameters": {
    "points": 11040
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-GUIN-1RYP",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7654811717",
   "rounded": "0.765",
   "label": "D",
   "nearest_distractor_gap": "0.0324811717",
   "parameters": {
    "q_per_nm": 0.15,
    "rg_nm": 5.969373616761955,
    "atoms": 6386
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-ASM-GUIN-1STM",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.7905362470",
   "rounded": "0.791",
   "label": "B",
   "nearest_distractor_gap": "0.0984637530",
   "parameters": {
    "q_per_nm": 0.12,
    "rg_nm": 6.997674764921086,
    "atoms": 8460
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-DEB-1RYP",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.3303923076",
   "rounded": "0.330",
   "label": "D",
   "nearest_distractor_gap": "0.2213923076",
   "parameters": {
    "q_per_nm": 0.3,
    "points": 6386
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-DEB-2BUK",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.2270694737",
   "rounded": "0.227",
   "label": "A",
   "nearest_distractor_gap": "0.0499305263",
   "parameters": {
    "q_per_nm": 0.25,
    "points": 11040
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-1RYP",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.2388353074",
   "rounded": "0.239",
   "label": "D",
   "nearest_distractor_gap": "0.0488353074",
   "parameters": {
    "target": 0.5,
    "rg_nm": 5.969373616761955,
    "points": 6386
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-ASM-T-1STM",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "1.0000000000",
   "rounded": "1",
   "label": "A",
   "nearest_distractor_gap": "2.0000000000",
   "parameters": {
    "component": "CP",
    "copies": 60,
    "T": 1
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-CAPS-2BUK",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "12.0000000000",
   "rounded": "12",
   "label": "C",
   "nearest_distractor_gap": "2.0000000000",
   "parameters": {
    "component": "CP",
    "copies": 60,
    "T": 1
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1CWP",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "24.2149360530",
   "rounded": "24.21",
   "label": "B",
   "nearest_distractor_gap": "6.4550639470",
   "parameters": {
    "points": 180
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1CWP",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "11.8772715248",
   "rounded": "11.88",
   "label": "C",
   "nearest_distractor_gap": "2.4972715248",
   "parameters": {
    "points": 180
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-1SVA",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "42.9178161892",
   "rounded": "42.92",
   "label": "B",
   "nearest_distractor_gap": "12.1221838108",
   "parameters": {
    "points": 360
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-1SVA",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "21.3178041016",
   "rounded": "21.32",
   "label": "A",
   "nearest_distractor_gap": "6.2021958984",
   "parameters": {
    "points": 360
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-ASM-EXT-2FT1",
   "family": "assembly_extent",
   "checker_version": "0.1.0",
   "recomputed": "59.8816994138",
   "rounded": "59.88",
   "label": "C",
   "nearest_distractor_gap": "36.6916994138",
   "parameters": {
    "points": 420
   },
   "method": "chunked brute force + Decimal pair",
   "status": "pass"
  },
  {
   "id": "FA-ASM-RG-2FT1",
   "family": "assembly_rg",
   "checker_version": "0.1.0",
   "recomputed": "28.0682869916",
   "rounded": "28.07",
   "label": "B",
   "nearest_distractor_gap": "11.8582869916",
   "parameters": {
    "points": 420
   },
   "method": "pair-distance identity",
   "status": "pass"
  },
  {
   "id": "FA-DEB-1CWP",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.2479737489",
   "rounded": "0.248",
   "label": "B",
   "nearest_distractor_gap": "0.0520262511",
   "parameters": {
    "q_per_nm": 0.16,
    "points": 180
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-1CWP",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.1171667207",
   "rounded": "0.117",
   "label": "A",
   "nearest_distractor_gap": "0.0328332793",
   "parameters": {
    "target": 0.5,
    "rg_nm": 11.877271524768261,
    "points": 180
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-DEB-1SVA",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.2401099902",
   "rounded": "0.240",
   "label": "C",
   "nearest_distractor_gap": "0.0528900098",
   "parameters": {
    "q_per_nm": 0.09,
    "points": 360
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-1SVA",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.0652770120",
   "rounded": "0.0653",
   "label": "B",
   "nearest_distractor_gap": "0.0193229880",
   "parameters": {
    "target": 0.5,
    "rg_nm": 21.31780410156418,
    "points": 360
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-DEB-2FT1",
   "family": "debye_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.2818006381",
   "rounded": "0.282",
   "label": "C",
   "nearest_distractor_gap": "0.0481993619",
   "parameters": {
    "q_per_nm": 0.065,
    "points": 420
   },
   "method": "direct orientation average (Gauss-Legendre x uniform phi quadrature)",
   "status": "pass"
  },
  {
   "id": "FA-QDES-2FT1",
   "family": "scattering_q_design",
   "checker_version": "0.1.0",
   "recomputed": "0.0495871840",
   "rounded": "0.0496",
   "label": "C",
   "nearest_distractor_gap": "0.0198871840",
   "parameters": {
    "target": 0.5,
    "rg_nm": 28.068286991553844,
    "points": 420
   },
   "method": "orientation-average quadrature; march + Illinois regula falsi",
   "status": "pass"
  },
  {
   "id": "FA-ASM-T-1CWP",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "3.0000000000",
   "rounded": "3",
   "label": "B",
   "nearest_distractor_gap": "1.0000000000",
   "parameters": {
    "component": "CP",
    "copies": 180,
    "T": 3
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-CAPS-1CWP",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "32.0000000000",
   "rounded": "32",
   "label": "C",
   "nearest_distractor_gap": "2.0000000000",
   "parameters": {
    "component": "CP",
    "copies": 180,
    "T": 3
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-HEX-1CWP",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "20.0000000000",
   "rounded": "20",
   "label": "A",
   "nearest_distractor_gap": "10.0000000000",
   "parameters": {
    "component": "CP",
    "copies": 180,
    "T": 3
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-T-2FT1",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "7.0000000000",
   "rounded": "7",
   "label": "C",
   "nearest_distractor_gap": "2.0000000000",
   "parameters": {
    "component": "gp5",
    "copies": 420,
    "T": 7
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ASM-HEX-2FT1",
   "family": "capsid_architecture",
   "checker_version": "0.1.0",
   "recomputed": "60.0000000000",
   "rounded": "60",
   "label": "A",
   "nearest_distractor_gap": "10.0000000000",
   "parameters": {
    "component": "gp5",
    "copies": 420,
    "T": 7
   },
   "method": "count copies; Caspar–Klug relations",
   "status": "pass"
  },
  {
   "id": "FA-ROT-7029-111",
   "family": "rotational_line",
   "checker_version": "0.1.0",
   "recomputed": "5068.3955939254",
   "rounded": "5068.4",
   "label": "D",
   "nearest_distractor_gap": "227.5955939254",
   "parameters": {
    "transition": "1_11",
    "constants_MHz": {
     "A": 4110.9777,
     "B": 1238.4844,
     "C": 957.4179
    }
   },
   "method": "Decimal centre of mass and inertia tensor; closed-form cubic eigenvalues; J=1 level table",
   "status": "pass"
  },
  {
   "id": "FA-ROT-G9-101",
   "family": "rotational_line",
   "checker_version": "0.1.0",
   "recomputed": "1878.1274602945",
   "rounded": "1878.1",
   "label": "A",
   "nearest_distractor_gap": "138.9725397055",
   "parameters": {
    "transition": "1_01",
    "constants_MHz": {
     "A": 1312.2616,
     "B": 1008.528,
     "C": 869.5994
    }
   },
   "method": "Decimal centre of mass and inertia tensor; closed-form cubic eigenvalues; J=1 level table",
   "status": "pass"
  },
  {
   "id": "FA-ROT-G2-110",
   "family": "rotational_line",
   "checker_version": "0.1.0",
   "recomputed": "1724.2732177928",
   "rounded": "1724.3",
   "label": "B",
   "nearest_distractor_gap": "730.8267822072",
   "parameters": {
    "transition": "1_10",
    "constants_MHz": {
     "A": 1510.495,
     "B": 213.7782,
     "C": 206.3637
    }
   },
   "method": "Decimal centre of mass and inertia tensor; closed-form cubic eigenvalues; J=1 level table",
   "status": "pass"
  },
  {
   "id": "FA-ISO-7095-111",
   "family": "isotopologue_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "transition": "1_11",
    "parent_MHz": 3554.9978,
    "shifts_MHz": {
     "A": -31.9878,
     "B": -37.6189,
     "C": -101.956,
     "D": -60.9187
    }
   },
   "method": "Decimal inertia tensor with the substituted mass; closed-form cubic eigenvalues",
   "status": "pass"
  },
  {
   "id": "FA-ISO-G9-110",
   "family": "isotopologue_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "transition": "1_10",
    "parent_MHz": 2320.7896,
    "shifts_MHz": {
     "A": -21.0196,
     "B": -20.8249,
     "C": -18.8057,
     "D": -28.7155
    }
   },
   "method": "Decimal inertia tensor with the substituted mass; closed-form cubic eigenvalues",
   "status": "pass"
  },
  {
   "id": "FA-ISO-G13-111",
   "family": "isotopologue_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "transition": "1_11",
    "parent_MHz": 3117.4913,
    "shifts_MHz": {
     "A": -73.091,
     "B": -21.0353,
     "C": -20.7735,
     "D": -20.9478
    }
   },
   "method": "Decimal inertia tensor with the substituted mass; closed-form cubic eigenvalues",
   "status": "pass"
  },
  {
   "id": "FA-DIST-6LYZ-SS30",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "2.0423116804",
   "rounded": "2.042",
   "label": "B",
   "nearest_distractor_gap": "0.0576883196",
   "parameters": {
    "atoms": [
     [
      "SG",
      "Cys",
      "30"
     ],
     [
      "SG",
      "Cys",
      "115"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-DIST-1CRN-SS16",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "2.0507630287",
   "rounded": "2.051",
   "label": "B",
   "nearest_distractor_gap": "0.2377630287",
   "parameters": {
    "atoms": [
     [
      "SG",
      "Cys",
      "16"
     ],
     [
      "SG",
      "Cys",
      "26"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-DIST-WP6-C20O22",
   "family": "named_bond_distance",
   "checker_version": "0.1.0",
   "recomputed": "1.2724323165",
   "rounded": "1.272",
   "label": "A",
   "nearest_distractor_gap": "0.2815676835",
   "parameters": {
    "atoms": [
     [
      "C20",
      "20"
     ],
     [
      "O22",
      "22"
     ]
    ]
   },
   "method": "Decimal distance; own bonding rule",
   "status": "pass"
  },
  {
   "id": "FA-COORD-SI",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "4 at 2.3516 Å",
   "parameters": {
    "partner": "Si",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-COORD-NACL-CL",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "6 at 2.8203 Å",
   "parameters": {
    "partner": "Cl",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-COORD-NACL-NA",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "12 at 3.9885 Å",
   "parameters": {
    "partner": "Na",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-SI",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "28.4437059050",
   "rounded": "28.44",
   "label": "D",
   "nearest_distractor_gap": "5.3037059050",
   "parameters": {
    "weights": {
     "Si": 14
    },
    "wavelength_A": 1.5406,
    "reflection": [
     1,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-DIAMOND",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "43.9326365778",
   "rounded": "43.93",
   "label": "A",
   "nearest_distractor_gap": "31.3673634222",
   "parameters": {
    "weights": {
     "C": 6
    },
    "wavelength_A": 1.5406,
    "reflection": [
     1,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-EXT-SI",
   "family": "kinematic_extinction",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "(2 0 0)",
   "parameters": {
    "weights": {
     "Si": 14
    },
    "a_A": 5.4307,
    "atoms": 8
   },
   "options": {
    "A": 0.70710678,
    "B": 0.0,
    "C": 0.70710678,
    "D": 1.0
   },
   "weakest_nonzero": 0.707107,
   "method": "separate cos/sin sums over the student table",
   "status": "pass"
  },
  {
   "id": "FA-GUIN-1UBQ",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.8917428108",
   "rounded": "0.892",
   "label": "B",
   "nearest_distractor_gap": "0.0522571892",
   "parameters": {
    "q_per_nm": 0.5,
    "rg_nm": 1.1725741768612346,
    "atoms": 602
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-GUIN-1CRN",
   "family": "guinier_intensity",
   "checker_version": "0.1.0",
   "recomputed": "0.9250900212",
   "rounded": "0.925",
   "label": "C",
   "nearest_distractor_gap": "0.0439099788",
   "parameters": {
    "q_per_nm": 0.5,
    "rg_nm": 0.9666285286168808,
    "atoms": 327
   },
   "method": "pair-distance Rg; Guinier law",
   "status": "pass"
  },
  {
   "id": "FA-FRET-1BNA",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.4799026258",
   "rounded": "0.480",
   "label": "B",
   "nearest_distractor_gap": "0.0400973742",
   "parameters": {
    "sites": [
     [
      "C1'",
      "Dc",
      "1"
     ],
     [
      "C1'",
      "Dg",
      "12"
     ]
    ],
    "R0_nm": 3.5,
    "r_nm": 3.5472350485977104
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "FC-BNP002-1UBQ",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "11.4928948762",
   "rounded": "11.4929",
   "label": "B",
   "nearest_distractor_gap": "0.0764051238",
   "parameters": {
    "measure": "equal_weight_rg",
    "atoms": 76
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-BNP002-1CRN",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "9.6755012693",
   "rounded": "9.6755",
   "label": "A",
   "nearest_distractor_gap": "0.1068987307",
   "parameters": {
    "measure": "equal_weight_rg",
    "atoms": 46
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FC-BNP001-1CRN",
   "family": "extent_choice_v2",
   "checker_version": "0.1.0",
   "recomputed": "29.0218591410",
   "rounded": "29.0219",
   "label": "B",
   "nearest_distractor_gap": "3.4000408590",
   "parameters": {
    "measure": "max_pair_distance",
    "atoms": 46
   },
   "method": "Decimal (40 digits) explicit sums",
   "status": "pass"
  },
  {
   "id": "FA-HBG-TWO-OO",
   "family": "hbond_geometry",
   "checker_version": "0.1.0",
   "recomputed": "2.5381167310",
   "rounded": "2.538",
   "label": "B",
   "nearest_distractor_gap": "0.0758832690",
   "parameters": {
    "rows": [
     6,
     5,
     14
    ],
    "quantity": "da"
   },
   "method": "Decimal distances; law of cosines; own covalent-radius bonding check",
   "status": "pass"
  },
  {
   "id": "FA-HBG-FIVE-HN",
   "family": "hbond_geometry",
   "checker_version": "0.1.0",
   "recomputed": "1.9264779391",
   "rounded": "1.926",
   "label": "B",
   "nearest_distractor_gap": "0.1694779391",
   "parameters": {
    "rows": [
     5,
     4,
     11
    ],
    "quantity": "ha"
   },
   "method": "Decimal distances; law of cosines; own covalent-radius bonding check",
   "status": "pass"
  },
  {
   "id": "FA-HBG-FOUR-ANG",
   "family": "hbond_geometry",
   "checker_version": "0.1.0",
   "recomputed": "128.5618357002",
   "rounded": "128.6",
   "label": "C",
   "nearest_distractor_gap": "21.2381642998",
   "parameters": {
    "rows": [
     3,
     5,
     13
    ],
    "quantity": "angle"
   },
   "method": "Decimal distances; law of cosines; own covalent-radius bonding check",
   "status": "pass"
  },
  {
   "id": "FA-HBC-SET1",
   "family": "hbond_criteria",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "ha_max": 2.2,
    "angle_min": 130.0,
    "verdicts": {
     "A": [
      true,
      1.6113,
      151.49
     ],
     "B": [
      false,
      2.4596,
      66.77
     ],
     "C": [
      false,
      2.6613,
      83.26
     ],
     "D": [
      false,
      3.7332,
      8.97
     ]
    }
   },
   "method": "Decimal distances; law of cosines; criteria read from the question",
   "status": "pass"
  },
  {
   "id": "FA-HBC-SET2",
   "family": "hbond_criteria",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "ha_max": 2.2,
    "angle_min": 130.0,
    "verdicts": {
     "A": [
      false,
      3.6894,
      10.16
     ],
     "B": [
      true,
      1.9265,
      138.28
     ],
     "C": [
      false,
      3.6837,
      18.17
     ],
     "D": [
      false,
      2.4569,
      67.69
     ]
    }
   },
   "method": "Decimal distances; law of cosines; criteria read from the question",
   "status": "pass"
  },
  {
   "id": "FA-FP-QM7X-7040-D1",
   "family": "force_path_derivative",
   "checker_version": "0.1.0",
   "recomputed": "11.8341124224",
   "rounded": "11.8341",
   "label": "C",
   "nearest_distractor_gap": "5.9170124224",
   "parameters": {
    "direction": "A_to_B",
    "atoms": 16
   },
   "method": "Decimal atom-by-atom projection",
   "status": "pass"
  },
  {
   "id": "FA-FP-QM7X-7040-D2",
   "family": "force_path_derivative",
   "checker_version": "0.1.0",
   "recomputed": "-5.0423222646",
   "rounded": "-5.0423",
   "label": "A",
   "nearest_distractor_gap": "4.4260222646",
   "parameters": {
    "direction": "B_to_A",
    "atoms": 16
   },
   "method": "Decimal atom-by-atom projection",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-CAO-COHERENCE",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "25.8",
   "mistake": "8.2",
   "parameters": {
    "card": "cao2018-coherence",
    "kind": "inverse_sqrt_density"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-CAO-SQUID",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "0.092",
   "mistake": "0.184",
   "parameters": {
    "card": "cao2018-squid",
    "kind": "flux_loop_area"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-CAO-PAULI",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "36.54",
   "mistake": "0.12",
   "parameters": {
    "card": "cao2018-pauli",
    "kind": "thin_film_parallel_field"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-KER-STRAIN",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "1.18",
   "mistake": "1.03",
   "parameters": {
    "card": "kerelsky2019-strain",
    "kind": "equal_area_twist"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-SCH-FLUX",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "28.6",
   "mistake": "14.3",
   "parameters": {
    "card": "schaefermeier2026-flux",
    "kind": "flux_quanta_count"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-SHA-BAND",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "85.9",
   "mistake": "592.7",
   "parameters": {
    "card": "shaban2024-band",
    "kind": "cholesteric_bandwidth"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-DIN-HTP",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "0.76",
   "mistake": "0.90",
   "parameters": {
    "card": "dinc2024-htp",
    "kind": "htp_ratio"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-ALT-OHSHIFT",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "-0.196",
   "mistake": "-0.315",
   "parameters": {
    "card": "altun2021-ohshift",
    "kind": "xyz_distance_difference"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-ALT-NHO",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "0.126",
   "mistake": "0.204",
   "parameters": {
    "card": "altun2021-nho",
    "kind": "xyz_distance_difference"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVE-KER-NEMATIC",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "card": "kerelsky2019-nematic",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-COT-BEND",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "card": "cottet2014-bend",
    "observations": 4
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-SHA-IONS",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "card": "shaban2024-ions",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-ALT-THREE",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "card": "altun2021-three",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-CAO-POCKETS",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "card": "cao2018-fermi-pockets",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-KER-BANDWIDTH",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "card": "kerelsky2019-bandwidth",
    "observations": 4
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-KER-GAP",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "card": "kerelsky2019-gap",
    "observations": 4
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-COT-LATTICE",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "card": "cottet2014-lattice",
    "observations": 4
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-ALT-STABILITY",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "card": "altun2021-stability",
    "observations": 3
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-FOO-LAYERS",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "5.93",
   "mistake": "0.17",
   "parameters": {
    "card": "fookes2023-layers",
    "kind": "layer_ratio"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVE-MUH-SKYRMION",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "card": "muhlbauer2009-skyrmion",
    "observations": 4
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-FIL-RBCS",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "0.075",
   "mistake": "-0.075",
   "parameters": {
    "card": "filip2014-rbcs",
    "kind": "photon_energy_shift"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVE-FIL-ANGLE",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "card": "filip2014-angle",
    "observations": 4
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-JIA-CHANNEL",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "card": "jiang2015-channel",
    "observations": 3
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-JIA-SEQUENCE",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "card": "jiang2015-sequence",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVQ-JIA-CLAMP",
   "family": "evidence_quantity",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "16.13",
   "mistake": "14.00",
   "parameters": {
    "card": "jiang2015-clamp",
    "kind": "regular_polygon_radius"
   },
   "method": "Decimal recomputation from the hashed card; 2×2 option structure",
   "status": "pass"
  },
  {
   "id": "FA-EVE-KCS-COLLAPSE",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "card": "cuello2017-collapse",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-EVE-RAS-DOMAIN",
   "family": "evidence_elimination",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "card": "rasmussen2011-domain",
    "observations": 5
   },
   "method": "predictions compared with observations from the hashed card; single survivor",
   "status": "pass"
  },
  {
   "id": "FA-COORD-CU",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "12 at 2.5562 Å",
   "parameters": {
    "partner": "Cu",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-CU",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "43.3169109192",
   "rounded": "43.32",
   "label": "B",
   "nearest_distractor_gap": "7.1330890808",
   "parameters": {
    "weights": {
     "Cu": 29
    },
    "wavelength_A": 1.5406,
    "reflection": [
     1,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-COORD-FE",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "8 at 2.4820 Å",
   "parameters": {
    "partner": "Fe",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-FE",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "44.6798451329",
   "rounded": "44.68",
   "label": "C",
   "nearest_distractor_gap": "10.8101548671",
   "parameters": {
    "weights": {
     "Fe": 26
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     1,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-COORD-MG",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "6 at 3.1969 Å",
   "parameters": {
    "partner": "Mg",
    "cell": {
     "a": 3.20927,
     "b": 3.20927,
     "c": 5.21033,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 2
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-MG",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "32.1809809199",
   "rounded": "32.18",
   "label": "D",
   "nearest_distractor_gap": "4.4009809199",
   "parameters": {
    "weights": {
     "Mg": 12
    },
    "wavelength_A": 1.5406,
    "reflection": [
     -1,
     0,
     0
    ],
    "cell": {
     "a": 3.20927,
     "b": 3.20927,
     "c": 5.21033,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 2
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-ALNI",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "8 at 2.4950 Å",
   "parameters": {
    "partner": "Al",
    "mu4_node": false
   },
   "method": "own periodic neighbour search over 27 cells",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-ALNI",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "31.0159427346",
   "rounded": "31.02",
   "label": "A",
   "nearest_distractor_gap": "13.4140572654",
   "parameters": {
    "weights": {
     "Al": 13,
     "Ni": 28
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     0,
     1
    ]
   },
   "method": "all (h k l) up to 5 with own structure-factor sum",
   "status": "pass"
  },
  {
   "id": "FA-COORD-B5H9",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "1 at 1.6543 Å",
   "parameters": {
    "partner": "B",
    "cell": {
     "a": 10.201,
     "b": 10.201,
     "c": 9.996,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 112
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-B5H9",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "8.6613058599",
   "rounded": "8.66",
   "label": "B",
   "nearest_distractor_gap": "4.3313058599",
   "parameters": {
    "weights": {
     "B": 5,
     "H": 1
    },
    "wavelength_A": 1.5406,
    "reflection": [
     -1,
     0,
     0
    ],
    "cell": {
     "a": 10.201,
     "b": 10.201,
     "c": 9.996,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 112
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-K2CUF4",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "2 at 1.9388 Å",
   "parameters": {
    "partner": "F",
    "cell": {
     "a": 4.147,
     "b": 4.147,
     "c": 12.73,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 14
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-K2CUF4",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "13.9020862934",
   "rounded": "13.90",
   "label": "B",
   "nearest_distractor_gap": "6.9620862934",
   "parameters": {
    "weights": {
     "Cu": 29,
     "F": 9,
     "K": 19
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     0,
     -2
    ],
    "cell": {
     "a": 4.147,
     "b": 4.147,
     "c": 12.73,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 14
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-MN2CO10",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "1 at 1.8223 Å",
   "parameters": {
    "partner": "C",
    "cell": {
     "a": 14.1257,
     "b": 6.8799,
     "c": 14.3121,
     "alpha": 90.0,
     "beta": 105.078,
     "gamma": 90.0
    },
    "cif_atoms": 88
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-MN2CO10",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "12.8014136994",
   "rounded": "12.80",
   "label": "C",
   "nearest_distractor_gap": "6.4114136994",
   "parameters": {
    "weights": {
     "C": 6,
     "Mn": 25,
     "O": 8
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     0,
     -2
    ],
    "cell": {
     "a": 14.1257,
     "b": 6.8799,
     "c": 14.3121,
     "alpha": 90.0,
     "beta": 105.078,
     "gamma": 90.0
    },
    "cif_atoms": 88
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-PARA-I",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "1 at 1.2399 Å",
   "parameters": {
    "partner": "C",
    "cell": {
     "a": 7.0915,
     "b": 9.2149,
     "c": 11.6015,
     "alpha": 90.0,
     "beta": 97.865,
     "gamma": 90.0
    },
    "cif_atoms": 80
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-PARA-I",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "12.3017145644",
   "rounded": "12.30",
   "label": "A",
   "nearest_distractor_gap": "1.5282854356",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1,
     "N": 7,
     "O": 8
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     -1,
     -1
    ],
    "cell": {
     "a": 7.0915,
     "b": 9.2149,
     "c": 11.6015,
     "alpha": 90.0,
     "beta": 97.865,
     "gamma": 90.0
    },
    "cif_atoms": 80
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-PARA-II",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "B",
   "recomputed": "1 at 1.2325 Å",
   "parameters": {
    "partner": "C",
    "cell": {
     "a": 11.8237,
     "b": 7.3971,
     "c": 17.1526,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 160
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-PARA-II",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "10.3061916935",
   "rounded": "10.31",
   "label": "B",
   "nearest_distractor_gap": "2.4338083065",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1,
     "N": 7,
     "O": 8
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     0,
     -2
    ],
    "cell": {
     "a": 11.8237,
     "b": 7.3971,
     "c": 17.1526,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 160
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-PENTACENE",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "C",
   "recomputed": "1 at 1.3962 Å",
   "parameters": {
    "partner": "C",
    "cell": {
     "a": 6.266,
     "b": 7.775,
     "c": 14.53,
     "alpha": 76.475,
     "beta": 87.682,
     "gamma": 84.684
    },
    "cif_atoms": 72
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-PENTACENE",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "6.2525643407",
   "rounded": "6.25",
   "label": "B",
   "nearest_distractor_gap": "3.1225643407",
   "parameters": {
    "weights": {
     "C": 6,
     "H": 1
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     0,
     -1
    ],
    "cell": {
     "a": 6.266,
     "b": 7.775,
     "c": 14.53,
     "alpha": 76.475,
     "beta": 87.682,
     "gamma": 84.684
    },
    "cif_atoms": 72
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-HAP",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "D",
   "recomputed": "1 at 1.4960 Å",
   "parameters": {
    "partner": "O",
    "cell": {
     "a": 9.4,
     "b": 9.4,
     "c": 6.93,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 42
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-HAP",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "10.8593609759",
   "rounded": "10.86",
   "label": "C",
   "nearest_distractor_gap": "1.4593609759",
   "parameters": {
    "weights": {
     "Ca": 20,
     "O": 8,
     "P": 15
    },
    "wavelength_A": 1.5406,
    "reflection": [
     -1,
     0,
     0
    ],
    "cell": {
     "a": 9.4,
     "b": 9.4,
     "c": 6.93,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 120.0
    },
    "cif_atoms": 42
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-COORD-ARAGONITE",
   "family": "coordination_shell",
   "checker_version": "0.1.0",
   "label": "A",
   "recomputed": "1 at 2.4127 Å",
   "parameters": {
    "partner": "O",
    "cell": {
     "a": 4.96183,
     "b": 7.96914,
     "c": 5.74285,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 20
   },
   "method": "metric-tensor neighbour search over 125 cells; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "FA-PEAK-ARAGONITE",
   "family": "first_diffraction_peak",
   "checker_version": "0.1.0",
   "recomputed": "19.0330262073",
   "rounded": "19.03",
   "label": "A",
   "nearest_distractor_gap": "2.0369737927",
   "parameters": {
    "weights": {
     "C": 6,
     "Ca": 20,
     "O": 8
    },
    "wavelength_A": 1.5406,
    "reflection": [
     0,
     -1,
     -1
    ],
    "cell": {
     "a": 4.96183,
     "b": 7.96914,
     "c": 5.74285,
     "alpha": 90.0,
     "beta": 90.0,
     "gamma": 90.0
    },
    "cif_atoms": 20
   },
   "method": "metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion",
   "status": "pass"
  },
  {
   "id": "EN-1A6M-TOR-2-PHI",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "-75.9986723322",
   "rounded": "-76.0",
   "label": "D",
   "nearest_distractor_gap": "138.7013276678",
   "parameters": {
    "atoms": "C(1)–N(2)–CA(2)–C(2)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "EN-1A6M-SS-6",
   "family": "secondary_structure",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "phi": -66.20020310231278,
    "psi": -44.188086996862985,
    "distances": {
     "right-handed α-helix": 9.62032181691533,
     "β-strand": 182.30717977594603,
     "polyproline II": 171.03843442113177,
     "left-handed α-helix": 153.2760818086063
    },
    "record": "HELIX"
   },
   "method": "acos dihedrals; nearest reference; HELIX/SHEET evidence",
   "status": "pass"
  },
  {
   "id": "EN-1A6M-FRET-1-15",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.4178526731",
   "rounded": "0.418",
   "label": "B",
   "nearest_distractor_gap": "0.0821473269",
   "parameters": {
    "sites": [
     [
      "CA",
      "Val",
      "1"
     ],
     [
      "CA",
      "Ala",
      "15"
     ]
    ],
    "R0_nm": 2.0,
    "r_nm": 2.113642905033866
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "EN-1A6M-DS-2-6",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "EN-1A6M-FD-25-1-18",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "efficiency": {
     "A": 0.2451,
     "B": 0.928,
     "C": 0.0968,
     "D": 0.9722
    },
    "R0_nm": 2.0
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "EN-1FHA-TOR-6-PHI",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "-64.5299939094",
   "rounded": "-64.5",
   "label": "A",
   "nearest_distractor_gap": "129.0299939094",
   "parameters": {
    "atoms": "C(5)–N(6)–CA(6)–C(6)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "EN-1FHA-FRET-5-22",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.4526843125",
   "rounded": "0.453",
   "label": "B",
   "nearest_distractor_gap": "0.0473156875",
   "parameters": {
    "sites": [
     [
      "CA",
      "Thr",
      "5"
     ],
     [
      "CA",
      "Arg",
      "22"
     ]
    ],
    "R0_nm": 2.0,
    "r_nm": 2.064288552988656
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "EN-1FHA-DS-6-9",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "EN-1FHA-FD-25-5-42",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "efficiency": {
     "A": 0.7495,
     "B": 0.2411,
     "C": 0.3764,
     "D": 0.9974
    },
    "R0_nm": 4.0
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "EN-12E8-TOR-2-PHI",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "-61.9317514121",
   "rounded": "-61.9",
   "label": "B",
   "nearest_distractor_gap": "86.4682485879",
   "parameters": {
    "atoms": "C(1)–N(2)–CA(2)–C(2)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "EN-12E8-SS-3",
   "family": "secondary_structure",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "phi": -148.4427531164259,
    "psi": 142.55734800850135,
    "distances": {
     "right-handed α-helix": 193.42304597799804,
     "β-strand": 31.09143280469024,
     "polyproline II": 73.48336229427625,
     "left-handed α-helix": 181.7117203777673
    },
    "record": "SHEET"
   },
   "method": "acos dihedrals; nearest reference; HELIX/SHEET evidence",
   "status": "pass"
  },
  {
   "id": "EN-12E8-FRET-1-8",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.7556052858",
   "rounded": "0.756",
   "label": "C",
   "nearest_distractor_gap": "0.1213947142",
   "parameters": {
    "sites": [
     [
      "CA",
      "Glu",
      "1"
     ],
     [
      "CA",
      "Gly",
      "8"
     ]
    ],
    "R0_nm": 2.5,
    "r_nm": 2.0712831819912987
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "EN-12E8-DS-7-21",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "EN-12E8-FD-25-1-11",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "efficiency": {
     "A": 0.3487,
     "B": 0.9478,
     "C": 0.2354,
     "D": 0.9353
    },
    "R0_nm": 2.5
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "EN-1HHK-TOR-2-PHI",
   "family": "backbone_torsion",
   "checker_version": "0.1.0",
   "recomputed": "-66.1432006053",
   "rounded": "-66.1",
   "label": "C",
   "nearest_distractor_gap": "77.3567993947",
   "parameters": {
    "atoms": "C(1)–N(2)–CA(2)–C(2)"
   },
   "method": "acos of plane normals with triple-product sign",
   "status": "pass"
  },
  {
   "id": "EN-1HHK-SS-3",
   "family": "secondary_structure",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "phi": -143.49850010856565,
    "psi": 156.50965320166142,
    "distances": {
     "right-handed α-helix": 178.80497521628365,
     "β-strand": 35.42514954413908,
     "polyproline II": 69.45874051511215,
     "left-handed α-helix": 193.4763360516355
    },
    "record": "SHEET"
   },
   "method": "acos dihedrals; nearest reference; HELIX/SHEET evidence",
   "status": "pass"
  },
  {
   "id": "EN-1HHK-FRET-1-7",
   "family": "fret_efficiency",
   "checker_version": "0.1.0",
   "recomputed": "0.7572371756",
   "rounded": "0.757",
   "label": "D",
   "nearest_distractor_gap": "0.1262371756",
   "parameters": {
    "sites": [
     [
      "CA",
      "Gly",
      "1"
     ],
     [
      "CA",
      "Tyr",
      "7"
     ]
    ],
    "R0_nm": 2.5,
    "r_nm": 2.0682278622047425
   },
   "method": "straight-line distance; Foerster law",
   "status": "pass"
  },
  {
   "id": "EN-1HHK-DS-5-168",
   "family": "disulfide_design",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "CA": [
     4.4,
     6.8
    ],
    "CB": [
     3.45,
     4.5
    ]
   },
   "method": "Decimal distances; stated windows",
   "status": "pass"
  },
  {
   "id": "EN-1HHK-FD-25-1-16",
   "family": "fret_design",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "efficiency": {
     "A": 0.133,
     "B": 0.9978,
     "C": 0.1432,
     "D": 0.2402
    },
    "R0_nm": 4.0
   },
   "method": "Decimal distances; Förster law",
   "status": "pass"
  },
  {
   "id": "FA-DES-VIN-WALLS",
   "family": "design_choice",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "card": "vincent2025-walls",
    "choice": "H2-NMeAc",
    "failures": {
     "H2-NMeAc": [],
     "H1-NMeAc": [
      "affinity"
     ],
     "H2-NMeQ": [
      "affinity"
     ],
     "H1-NMeQ": [
      "affinity"
     ]
    }
   },
   "method": "Decimal re-evaluation of the thresholds parsed from the question against the hashed card",
   "status": "pass"
  },
  {
   "id": "FA-DES-VIN-MV",
   "family": "design_choice",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "card": "vincent2025-viologen",
    "choice": "H1-MV",
    "failures": {
     "H2-MV": [
      "affinity"
     ],
     "H1-MV": [],
     "H2-NMeQ": [
      "affinity"
     ],
     "H1-NMeQ": [
      "affinity"
     ]
    }
   },
   "method": "Decimal re-evaluation of the thresholds parsed from the question against the hashed card",
   "status": "pass"
  },
  {
   "id": "FA-DES-RAN-NITRATE",
   "family": "design_choice",
   "checker_version": "0.1.0",
   "label": "C",
   "parameters": {
    "card": "rando2025-nitrate",
    "choice": "BnBU-CHCl3",
    "failures": {
     "BU2-CHCl3": [
      "selectivity"
     ],
     "BU1-MeCN": [
      "selectivity"
     ],
     "BnBU-CHCl3": [],
     "BU1-CHCl3": [
      "selectivity"
     ]
    }
   },
   "method": "Decimal re-evaluation of the thresholds parsed from the question against the hashed card",
   "status": "pass"
  },
  {
   "id": "FA-DES-RAN-BROMIDE",
   "family": "design_choice",
   "checker_version": "0.1.0",
   "label": "D",
   "parameters": {
    "card": "rando2025-bromide",
    "choice": "BU2-CHCl3",
    "failures": {
     "BnBU-CHCl3": [
      "affinity"
     ],
     "BU1-MeCN": [
      "affinity"
     ],
     "BU1-CHCl3": [
      "affinity"
     ],
     "BU2-CHCl3": []
    }
   },
   "method": "Decimal re-evaluation of the thresholds parsed from the question against the hashed card",
   "status": "pass"
  },
  {
   "id": "FA-DES-CHE-SIEVE",
   "family": "design_choice",
   "checker_version": "0.1.0",
   "label": "A",
   "parameters": {
    "card": "chetry2026-sieving",
    "choice": "UTSA-16(Co)",
    "failures": {
     "UTSA-16(Co)": [],
     "Cu-tetrazolate": [
      "capacity"
     ],
     "Ag-Bpz": [
      "selectivity"
     ],
     "Cu-4Py-Me": [
      "selectivity"
     ]
    }
   },
   "method": "Decimal re-evaluation of the thresholds parsed from the question against the hashed card",
   "status": "pass"
  },
  {
   "id": "FA-DES-CHE-FLOW",
   "family": "design_choice",
   "checker_version": "0.1.0",
   "label": "B",
   "parameters": {
    "card": "chetry2026-throughput",
    "choice": "Cu-4Py-Me",
    "failures": {
     "Ag-Bpz": [
      "capacity"
     ],
     "Cu-4Py-Me": [],
     "Cu-tetrazolate": [
      "capacity"
     ],
     "UTSA-16(Co)": [
      "capacity"
     ]
    }
   },
   "method": "Decimal re-evaluation of the thresholds parsed from the question against the hashed card",
   "status": "pass"
  }
 ],
 "checker_code": {
  "checkers/__init__.py": "\"\"\"Independent answer checkers (see common.py for the independence rule).\"\"\"\nfrom .common import CheckError, VERSION, packet_shape\nfrom .families import CHECKERS\n\n\ndef check(packet, key):\n    \"\"\"Returns a report dict; status is 'pass' only if every check succeeded.\"\"\"\n    report = dict(id=packet['id'], family=packet['family'], checker_version=VERSION)\n    try:\n        if packet['id'] != key['id'] or packet['family'] != key['family']:\n            raise CheckError('Packet and key do not belong together')\n        if packet['family'] not in CHECKERS:\n            raise CheckError('No independent checker for family ' + packet['family'])\n        if not key.get('input_hashes'):\n            raise CheckError('No source asset recorded in the answer key')\n        packet_shape(packet)\n        report.update(CHECKERS[packet['family']](packet, key))\n        report['status'] = 'pass'\n    except CheckError as error:\n        report.update(status='fail', problem=str(error))\n    except (KeyError, ValueError, IndexError, ArithmeticError) as error:\n        report.update(status='fail', problem='Malformed packet or key: %s: %s' % (type(error).__name__, error))\n    return report\n",
  "checkers/cells.py": "\"\"\"Independent geometry for crystal cells of any system (checker side; imports no generation code).\n\nDifferent methods from the generator (task_families/cell.py):\n  - geometry from the metric tensor G (distance^2 = df' G df) and its numerical inverse for d-spacings,\n    instead of lattice and reciprocal vectors;\n  - its own CIF expansion (character scanner for symmetry operations), used to confirm that the student\n    table is exactly the symmetry-expanded source: a reader bug in the generator cannot hide behind a\n    checker that only trusts the table.\n\"\"\"\nimport math\nimport re\nfrom fractions import Fraction\n\nimport numpy as np\n\nfrom .common import need, find\n\nHEADER = re.compile(r'cell a = ([\\d.]+) b = ([\\d.]+) c = ([\\d.]+) angstrom, alpha = ([\\d.]+) beta = ([\\d.]+) gamma = ([\\d.]+) degree')\nMATCH_TOL = 2e-4      # fractional: table vs own CIF expansion (the generator snaps 0.3333 to 1/3)\n\n\ndef parse_table(text):\n    \"\"\"(params or None, rows) from a fractional-cell table; params is None for the cubic header.\"\"\"\n    lines = text.splitlines()\n    rows = [(r[0], [float(x) for x in r[1:]]) for r in (l.split() for l in lines[1:] if l.strip())]\n    m = HEADER.search(lines[0])\n    if not m:\n        return None, rows\n    return dict(zip(('a', 'b', 'c', 'alpha', 'beta', 'gamma'), (float(x) for x in m.groups()))), rows\n\n\ndef metric(p):\n    ca, cb, cg = (math.cos(math.radians(p[k])) for k in ('alpha', 'beta', 'gamma'))\n    a, b, c = p['a'], p['b'], p['c']\n    return np.array([[a * a, a * b * cg, a * c * cb], [a * b * cg, b * b, b * c * ca], [a * c * cb, b * c * ca, c * c]])\n\n\ndef distance(G, f, g):\n    v = np.array(g, dtype=float) - np.array(f, dtype=float)\n    return math.sqrt(float(v @ G @ v))\n\n\ndef d_spacing(Ginv, hkl):\n    h = np.array(hkl, dtype=float)\n    return 1 / math.sqrt(float(h @ Ginv @ h))\n\n\ndef _value(token):\n    return float(token.split('(')[0])\n\n\ndef _symop(text):\n    \"\"\"Character scanner: returns three (coefficients over x, y, z; translation) with fractions.\"\"\"\n    out = []\n    for part in text.replace(' ', '').lower().split(','):\n        coeff, shift, sign, number = [Fraction(0)] * 3, Fraction(0), 1, ''\n        for ch in part + '+':\n            if ch in 'xyz':\n                coeff['xyz'.index(ch)] += sign * (Fraction(number) if number else 1)\n                number, sign = '', 1\n            elif ch in '+-':\n                if number:\n                    shift += sign * Fraction(number)\n                number, sign = '', (1 if ch == '+' else -1)\n            elif ch != '*':\n                number += ch\n        out.append((coeff, shift))\n    need(len(out) == 3, 'Bad symmetry operation: ' + text)\n    return out\n\n\ndef cif_cell(path):\n    \"\"\"Cell parameters and the symmetry-expanded atoms of a CIF, read with this module's own parser.\"\"\"\n    text = path.read_text(encoding='utf-8')\n    params = {k: _value(find(r'_cell_(?:length|angle)_%s\\s+(\\S+)' % k, text, 'CIF lacks ' + k).group(1))\n              for k in ('a', 'b', 'c', 'alpha', 'beta', 'gamma')}\n    ops, sites = [], []\n    tags, state = [], None                        # state: None (outside a loop), 'tags', 'rows'\n    for raw in text.splitlines():\n        line = raw.strip()\n        if line == 'loop_':\n            tags, state = [], 'tags'\n            continue\n        if line.startswith('_'):\n            if state == 'tags':\n                tags.append(line)\n            else:\n                state = None                      # a plain data item after the rows ends the loop\n            continue\n        if state is None or not line or line.startswith('#'):\n            continue\n        state = 'rows'\n        values = re.findall(r\"'[^']*'|\\\"[^\\\"]*\\\"|\\S+\", line)\n        if len(values) != len(tags):\n            continue\n        row = dict(zip(tags, (v.strip('\\'\"') for v in values)))\n        op = row.get('_symmetry_equiv_pos_as_xyz') or row.get('_space_group_symop_operation_xyz')\n        if op:\n            ops.append(_symop(op))\n        if '_atom_site_fract_x' in row:\n            element = re.match(r'[A-Z][a-z]?', row.get('_atom_site_type_symbol') or row['_atom_site_label']).group(0)\n            sites.append((element, [_value(row['_atom_site_fract_' + k]) for k in 'xyz']))\n    need(ops and sites, 'CIF symmetry operations or sites not found')\n    atoms = []\n    for element, f in sites:\n        for op in ops:\n            g = [(float(sum(c * x for c, x in zip(coeff, f)) + shift)) % 1.0 for coeff, shift in op]\n            if not any(e == element and all(min(abs(x - y), 1 - abs(x - y)) < MATCH_TOL for x, y in zip(g, h)) for e, h in atoms):\n                atoms.append((element, g))\n    return params, atoms\n\n\ndef same_cell(params, rows, path):\n    \"\"\"The student table must be exactly the symmetry-expanded CIF (parameters and every atom).\"\"\"\n    src_params, src_atoms = cif_cell(path)\n    need(all(abs(params[k] - src_params[k]) < 1e-4 for k in params), 'Cell parameters differ from the CIF')\n    need(len(rows) == len(src_atoms), 'Table has %d atoms, the expanded CIF %d' % (len(rows), len(src_atoms)))\n    for e, f in rows:\n        need(any(e == s and all(min(abs(x - y) % 1, 1 - abs(x - y) % 1) < MATCH_TOL for x, y in zip(f, g)) for s, g in src_atoms),\n             'Table atom %s %s not in the expanded CIF' % (e, f))\n    return len(src_atoms)\n",
  "checkers/common.py": "\"\"\"Shared helpers for independent answer checkers.\n\nIndependence rule: nothing under checkers/ imports the question-generation code\n(task_families, family_engine, template_engine, choice_engine or tools). A checker\nsees only what the tested model sees (question text, attached inputs, options) plus\nthe answer key, and recomputes with its own implementation. Provenance checks may\nread the public source asset named in the answer key and verify its SHA-256.\n\"\"\"\nimport hashlib\nimport math\nimport re\nfrom decimal import Decimal, ROUND_HALF_UP, localcontext\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[1]\nVERSION = '0.1.0'\nLABELS = ['A', 'B', 'C', 'D']\n# Answer-key vocabulary that must never appear in a student packet.\nFORBIDDEN_KEYS = {'correct_label', 'is_correct', 'option_audit', 'reason', 'source_id', 'numeric_answer',\n                  'explanation', 'excluded_candidates', 'rank', 'checks'}\n\n\nclass CheckError(Exception):\n    \"\"\"A check that fails; the message is reported verbatim.\"\"\"\n\n\ndef need(condition, message):\n    if not condition:\n        raise CheckError(message)\n\n\ndef find(pattern, text, message, flags=0):\n    match = re.search(pattern, text, flags)\n    need(match is not None, message)\n    return match\n\n\ndef read_xyz(text):\n    \"\"\"Returns [(element, (Decimal x, y, z))]; strict count and row format.\"\"\"\n    lines = text.splitlines()\n    need(len(lines) >= 3 and lines[0].strip().isdigit(), 'XYZ header invalid')\n    rows = [line.split() for line in lines[2:] if line.strip()]\n    need(len(rows) == int(lines[0]), 'XYZ atom count does not match rows')\n    atoms = []\n    for row in rows:\n        need(len(row) == 4 and row[0].isalpha(), 'XYZ row must be element x y z')\n        coords = tuple(Decimal(v) for v in row[1:])\n        need(all(c.is_finite() for c in coords), 'Nonfinite coordinate')\n        atoms.append((row[0].capitalize(), coords))\n    return atoms\n\n\ndef dist(p, q):\n    with localcontext() as ctx:\n        ctx.prec = 40\n        return sum((a - b) ** 2 for a, b in zip(p, q)).sqrt()\n\n\ndef vec(p, q):\n    \"\"\"q - p as floats.\"\"\"\n    return [float(b) - float(a) for a, b in zip(p, q)]\n\n\ndef dot(u, v):\n    return math.fsum(a * b for a, b in zip(u, v))\n\n\ndef cross(u, v):\n    return [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]]\n\n\ndef rounded(value, decimals):\n    return Decimal(str(value)).quantize(Decimal(1).scaleb(-decimals), rounding=ROUND_HALF_UP)\n\n\ndef sha256_file(rel):\n    path = (ROOT / 'docs' / rel).resolve()\n    need(path.is_relative_to((ROOT / 'docs/assets').resolve()), 'Evidence asset outside docs/assets')\n    need(path.exists(), 'Evidence asset missing: ' + rel)\n    return hashlib.sha256(path.read_bytes()).hexdigest(), path\n\n\ndef verify_hashes(key):\n    \"\"\"Every reviewer-side asset named in the key must match its recorded SHA-256.\"\"\"\n    paths = {}\n    for rel, digest in key['input_hashes'].items():\n        actual, path = sha256_file(rel)\n        need(actual == digest, 'Asset hash mismatch: ' + rel)\n        paths[rel] = path\n    return paths\n\n\ndef packet_shape(packet):\n    need([o['label'] for o in packet['options']] == LABELS, 'Options must be exactly A, B, C, D')\n    need(len({o['value'] for o in packet['options']}) == 4, 'Duplicate option values')\n    leaked = FORBIDDEN_KEYS & _keys(packet)\n    need(not leaked, 'Answer-key fields in student packet: ' + ', '.join(sorted(leaked)))\n\n\ndef _keys(obj):\n    if isinstance(obj, dict):\n        return set(obj) | set().union(*(_keys(v) for v in obj.values()))\n    if isinstance(obj, list):\n        return set().union(*(_keys(v) for v in obj)) if obj else set()\n    return set()\n\n\ndef gap(a, b, period=None):\n    d = abs(a - b)\n    if period is not None:\n        d = min(d % period, period - d % period)\n    return d\n\n\ndef judge_numeric(packet, key, value, period=None):\n    \"\"\"Recomputed value vs. options and key: exactly one option equals the rounded value,\n    the other three lie outside the tolerance, and key label / numeric key agree.\"\"\"\n    numeric = key['numeric_answer']\n    decimals, tol = numeric['decimals'], Decimal(numeric['tolerance'])\n    expected = rounded(value, decimals)\n    exact = Decimal(repr(value)) if isinstance(value, float) else Decimal(value)\n    units = {o.get('unit') for o in packet['options']}\n    need(units == {numeric['unit']}, 'Option units differ from the answer unit')\n    for o in packet['options']:\n        need(re.fullmatch(r'-?\\d+\\.\\d{%d}' % decimals if decimals else r'-?\\d+', o['value']) is not None,\n             'Option %s not shown with %d decimals' % (o['label'], decimals))\n    hits = [o['label'] for o in packet['options'] if gap(Decimal(o['value']), exact, period) <= tol]\n    need(len(hits) == 1, 'Recomputed value matches %d options (need exactly 1)' % len(hits))\n    label = hits[0]\n    shown = next(o['value'] for o in packet['options'] if o['label'] == label)\n    need(Decimal(shown) == expected or (period and gap(Decimal(shown), expected, period) == 0),\n         'Matching option %s is not the rounded recomputed value %s' % (shown, expected))\n    need(Decimal(numeric['value']) == expected, 'Numeric key %s != recomputed %s' % (numeric['value'], expected))\n    need(key['correct_label'] == label, 'Key label %s != recomputed label %s' % (key['correct_label'], label))\n    nearest = min(gap(Decimal(o['value']), exact, period) for o in packet['options'] if o['label'] != label)\n    q = Decimal('1e-10')\n    return dict(recomputed=str(exact.quantize(q)), rounded=str(expected), label=label,\n                nearest_distractor_gap=str(nearest.quantize(q)))\n",
  "checkers/design_extra.py": "\"\"\"Independent checkers for diffraction_design, disulfide_design and fret_design. No generation code is imported;\nparameters (weights, wavelengths, targets, windows, R0) are read from the question and options.\"\"\"\nimport cmath\nimport itertools\nimport math\nimport re\nfrom .common import need, find, verify_hashes, judge_numeric\nfrom .migrated import pdb_atoms, verbatim, dec_dist\n\n\ndef parse_table(text):\n    lines = text.splitlines()\n    a = float(find(r'cubic a = ([\\d.]+) angstrom', lines[0], 'Cell edge missing').group(1))\n    return a, [(r[0], [float(x) for x in r[1:]]) for r in (l.split() for l in lines[1:] if l.strip())]\n\n\ndef first_d(a, rows, weights):\n    need({e for e, _ in rows} <= set(weights), 'Weights must cover the elements present')\n    total = sum(weights[e] for e, _ in rows)\n    best = None\n    for h, k, l in itertools.product(range(6), repeat=3):\n        if (h, k, l) == (0, 0, 0):\n            continue\n        f = abs(sum(weights[e] * cmath.exp(2j * math.pi * (h * x + k * y + l * z)) for e, (x, y, z) in rows)) / total\n        g = h * h + k * k + l * l\n        if f > 1e-6 and (best is None or g < best):\n            best = g\n    return a / math.sqrt(best)\n\n\ndef weights_of(text):\n    return {k: int(v) for k, v in re.findall(r'([A-Z][a-z]?) = (\\d+)', text)}\n\n\ndef tth(d, lam):\n    return 2 * math.degrees(math.asin(lam / (2 * d)))\n\n\ndef closest(values, target):\n    ranked = sorted(values, key=lambda k: abs(values[k] - target))\n    need(abs(values[ranked[1]] - target) > abs(values[ranked[0]] - target) + 1e-9, 'Tie for closest candidate')\n    return ranked[0]\n\n\ndef diffraction_design(packet, key):\n    q = packet['question']\n    verify_hashes(key)\n    need('lowest-angle reflection with non-zero intensity' in q and 'atomic numbers as angle-independent weights' in q, 'Rule not stated')\n    if 'four crystals' in q:\n        lam = float(find(r'wavelength ([\\d.]+) Å', q, 'Wavelength missing').group(1))\n        target = float(find(r'closest to 2θ = ([\\d.]+)°', q, 'Target missing').group(1))\n        block = find(r'Weights: (.+?)\\. For X-rays', q, 'Weights missing').group(1)\n        per = {name.strip(): weights_of(w) for name, w in re.findall(r'([^;:]+?): ((?:[A-Z][a-z]? = \\d+(?:, )?)+)', block)}\n        values = {}\n        for inp in packet['inputs']:\n            short = [o['value'].split(' (')[0] for o in packet['options'] if o['value'].endswith('(%s)' % inp['name'])]\n            need(len(short) == 1 and short[0].strip() in per, 'Option/file/weights mismatch for ' + inp['name'])\n            a, rows = parse_table(inp['text'])\n            values[inp['name']] = tth(first_d(a, rows, per[short[0].strip()]), lam)\n        win = closest(values, target)\n        hits = [o['label'] for o in packet['options'] if o['value'].endswith('(%s)' % win)]\n    else:\n        weights = weights_of(find(r'Weights: ([^.]+)\\.', q, 'Weights missing').group(1))\n        [inp] = packet['inputs']\n        a, rows = parse_table(inp['text'])\n        d = first_d(a, rows, weights)\n        target = float(find(r'2θ = ([\\d.]+)°', q, 'Target missing').group(1))\n        if 'What wavelength' in q:\n            return dict(judge_numeric(packet, key, 2 * d * math.sin(math.radians(target / 2))), parameters=dict(d_A=d),\n                        method='own structure-factor search; Bragg law')\n        values = {}\n        for o in packet['options']:\n            lam = float(find(r'λ = ([\\d.]+) Å', o['value'], 'Option wavelength missing').group(1))\n            values[o['label']] = tth(d, lam) if lam < 2 * d else float('inf')\n        hits = [closest(values, target)]\n    need(len(hits) == 1 and key['correct_label'] == hits[0], 'Key label disagrees with recomputed choice')\n    return dict(label=hits[0], parameters=dict(values={k: round(v, 4) for k, v in values.items()}), method='own structure-factor search; Bragg law')\n\n\ndef pair_atoms(option, atoms, atom_names):\n    m = re.fullmatch(r'([A-Z][a-z]{0,2})(\\d+)–([A-Z][a-z]{0,2})(\\d+)', option)\n    need(m is not None, 'Option is not a residue pair')\n    out = []\n    for name in atom_names:\n        pts = [atoms.get((name, m.group(1), int(m.group(2)))), atoms.get((name, m.group(3), int(m.group(4))))]\n        need(all(pts), 'Atom %s missing for %s' % (name, option))\n        out.append(float(dec_dist(*pts)))\n    return out\n\n\ndef disulfide_design(packet, key):\n    q = packet['question']\n    ca = [float(x) for x in find(r'Cα–Cα distance between ([\\d.]+) and ([\\d.]+) Å', q, 'Cα window missing').groups()]\n    cb = [float(x) for x in find(r'Cβ–Cβ distance between ([\\d.]+) and ([\\d.]+) Å', q, 'Cβ window missing').groups()]\n    need('both inclusive' in q, 'Window convention missing')\n    [inp] = packet['inputs']\n    verbatim(inp['text'], key)\n    atoms = pdb_atoms(inp['text'])\n    ok = []\n    for o in packet['options']:\n        dca, dcb = pair_atoms(o['value'], atoms, ('CA', 'CB'))\n        if ca[0] <= dca <= ca[1] and cb[0] <= dcb <= cb[1]:\n            ok.append(o['label'])\n    need(len(ok) == 1, '%d pairs meet both windows' % len(ok))\n    need(key['correct_label'] == ok[0], 'Key label disagrees with recomputed choice')\n    return dict(label=ok[0], parameters=dict(CA=ca, CB=cb), method='Decimal distances; stated windows')\n\n\ndef fret_design(packet, key):\n    q = packet['question']\n    r0 = float(find(r'R0 = ([\\d.]+) nm', q, 'R0 missing').group(1))\n    target = float(find(r'as close as possible to ([\\d.]+)\\.', q, 'Target missing').group(1))\n    atom = find(r'point at the (\\S+) atom', q, 'Dye atom missing').group(1)\n    need('point-dipole Förster law' in q, 'Model not stated')\n    [inp] = packet['inputs']\n    verbatim(inp['text'], key)\n    atoms = pdb_atoms(inp['text'])\n    eff = {}\n    for o in packet['options']:\n        r = pair_atoms(o['value'], atoms, (atom,))[0] / 10\n        eff[o['label']] = 1 / (1 + (r / r0) ** 6)\n    win = closest(eff, target)\n    need(key['correct_label'] == win, 'Key label disagrees with recomputed choice')\n    return dict(label=win, parameters=dict(efficiency={k: round(v, 4) for k, v in eff.items()}, R0_nm=r0), method='Decimal distances; Förster law')\n\n\nCHECKERS = {'diffraction_design': diffraction_design, 'disulfide_design': disulfide_design, 'fret_design': fret_design}\n",
  "checkers/evidence.py": "\"\"\"Independent checkers for evidence_quantity and evidence_elimination. No generation code is imported.\n\nThe checker reads the evidence card named in the answer key (hash-verified), and requires that the student's\nevidence.txt lists exactly the card's facts and that every stored number is printed in its fact. Quantities are\nrecomputed with Decimal arithmetic and different formula routes (generator: floats). For the 2x2 quantity options the\nchecker parses each option into value and conclusion and requires the four combinations, exactly one of which is the\nrecomputed value with the paper's conclusion. For elimination it re-runs the comparison of predictions with\nobservations and requires a single surviving explanation, the paper's. What the card says about the paper is not\nsomething code can verify (L1 compares each locator with the original).\n\"\"\"\nimport json\nimport math\nimport re\nfrom decimal import Decimal, localcontext, ROUND_HALF_UP\nfrom .common import need, read_xyz, dist, verify_hashes\n\nH = Decimal('6.62607015e-34')\nE = Decimal('1.602176634e-19')\nUNIT_TEXT = {'nm': ' nm', 'um^2': ' µm²', 'T': ' T', 'degree': '°', 'angstrom': ' Å', 'eV': ' eV', '': ''}\nNUM = re.compile(r'(-?\\d+(?:\\.\\d+)?)(?: × 10\\^(-?\\d+))?')\n\n\ndef ctx():\n    return localcontext(prec=50)\n\n\ndef number(display):\n    m = NUM.match(display)\n    need(m is not None, 'Display string does not start with a number: ' + display)\n    base = Decimal(m.group(1))\n    return base * (Decimal(10) ** int(m.group(2))) if m.group(2) else base\n\n\ndef card_of(packet, key):\n    paths = verify_hashes(key)\n    cards = [p for rel, p in paths.items() if rel.startswith('assets/families/evidence/') and rel.endswith('.json')]\n    need(len(cards) == 1, 'Exactly one evidence card must be recorded in the key')\n    card = json.loads(cards[0].read_text(encoding='utf-8'))\n    need(card.get('family') == packet['family'], 'Card belongs to another family')\n    inputs = {i['name']: i['text'] for i in packet['inputs']}\n    need('evidence.txt' in inputs, 'No evidence.txt attached')\n    lines = inputs['evidence.txt'].rstrip('\\n').split('\\n')\n    need(len(lines) == len(card['facts']), 'evidence.txt does not list exactly the card facts')\n    for line, fact in zip(lines, card['facts']):\n        need(line == '%s. %s' % (fact['id'], fact['text']), 'Fact %s differs from the card' % fact['id'])\n    need(packet['question'].count('evidence.txt') >= 1 and card['ask'] in packet['question'], 'Question does not point to the evidence or ask the card question')\n    for f in card.get('files', []):\n        need(f['name'] in inputs, 'Structure file not attached: ' + f['name'])\n        source = [p for rel, p in paths.items() if rel == f['asset']]\n        need(len(source) == 1 and source[0].read_bytes().decode('utf-8') == inputs[f['name']], 'Attached structure differs from its asset')\n    return card, inputs\n\n\ndef fact_numbers(card):\n    out = {}\n    for f in card['facts']:\n        for name, (value, display) in f.get('values', {}).items():\n            need(display in f['text'], 'Number %s not printed in %s' % (name, f['id']))\n            parsed = number(display)\n            need(abs(parsed - Decimal(repr(value))) <= abs(parsed) * Decimal('1e-12'), 'Printed %s differs from the stored value' % name)\n            out[name] = parsed\n    return out\n\n\ndef flux(kind):\n    need(kind in ('h/2e', 'h/e'), 'Unknown flux quantum')\n    return H / (2 * E) if kind == 'h/2e' else H / E\n\n\ndef get(v, x):\n    return v[x] if isinstance(x, str) else Decimal(repr(x))\n\n\ndef asin_deg(x):\n    # asin via atan2 (the generator uses math.asin)\n    x = float(x)\n    return Decimal(repr(math.degrees(math.atan2(x, math.sqrt(1 - x * x)))))\n\n\ndef quantity(kind, a, v, inputs, card):\n    with ctx():\n        if kind == 'inverse_sqrt_density':\n            return Decimal(10) ** 7 / get(v, a['n_cm2']).sqrt()\n        if kind == 'flux_loop_area':\n            return flux(a['flux']) * Decimal(10) ** 15 / get(v, a['period_mT'])          # Wb / mT -> µm²\n        if kind == 'thin_film_parallel_field':\n            d, xi = get(v, a['d_nm']) * Decimal('1e-9'), get(v, a['xi_nm']) * Decimal('1e-9')\n            return Decimal(3).sqrt() * flux('h/2e') / (Decimal(repr(math.pi)) * d * xi)\n        if kind == 'perpendicular_gl_field':\n            xi = get(v, a['xi_nm']) * Decimal('1e-9')\n            return flux('h/2e') / (2 * Decimal(repr(math.pi)) * xi * xi)\n        if kind == 'equal_area_twist':\n            x, y, z = (get(v, a[k]) for k in ('l1', 'l2', 'l3'))\n            area = (4 * x * x * y * y - (x * x + y * y - z * z) ** 2).sqrt() / 4          # Heron, product-free form\n            side = (4 * area / Decimal(3).sqrt()).sqrt()\n            return 2 * asin_deg(get(v, a['a_nm']) / (2 * side))\n        if kind == 'single_wavelength_twist':\n            return 2 * asin_deg(get(v, a['a_nm']) / (2 * get(v, a['l'])))\n        if kind == 'flux_quanta_count':\n            side = get(v, a['side_um']) * Decimal('1e-6')\n            return get(v, a['B_mT']) * Decimal('1e-3') * side * side / flux(a['flux'])\n        if kind in ('cholesteric_bandwidth', 'cholesteric_centre'):\n            ne, no = get(v, a['ne']), get(v, a['no'])\n            index = ne - no if kind == 'cholesteric_bandwidth' else (ne + no) / 2\n            return index * Decimal(100000) / (get(v, a['htp_um']) * get(v, a['c_wt']))    # nm\n        if kind == 'htp_ratio':\n            return (get(v, a['lam_R']) * get(v, a['c_R'])) / (get(v, a['lam_L']) * get(v, a['c_L']))\n        if kind == 'wavelength_ratio':\n            return get(v, a['lam_R']) / get(v, a['lam_L'])\n        if kind == 'photon_energy_shift':               # same formula, Decimal arithmetic\n            hc = get(v, a['hc'])\n            return hc / get(v, a['lam_to']) - hc / get(v, a['lam_from'])\n        if kind == 'regular_polygon_radius':            # via the half-angle: R = side / (2 sin(pi/n))\n            n = int(get(v, a['n']))\n            need(n >= 3, 'A polygon needs at least three vertices')\n            half = Decimal(repr(math.sin(math.pi / n)))\n            return get(v, a['side']) / (2 * half)\n        if kind == 'layer_ratio':                       # k proportional to 1/v at fixed suspension\n            return get(v, a['v_fast']) / get(v, a['v_slow'])\n        if kind == 'layer_ratio_inverted':\n            return get(v, a['v_slow']) / get(v, a['v_fast'])\n        if kind == 'xyz_distance_difference':\n            names = {f['key']: f['name'] for f in card['files']}\n            facts = ' '.join(f['text'] for f in card['facts'])\n\n            def d(key, rows):\n                for r in rows:\n                    need('row %d' % r in facts, 'Row %d not named in the evidence' % r)\n                atoms = read_xyz(inputs[names[key]])\n                i, j = rows\n                return dist(atoms[i - 1][1], atoms[j - 1][1])\n            return d(a['a_file'], a['a_rows']) - d(a['b_file'], a['b_rows'])\n    need(False, 'Unknown quantity kind ' + kind)\n\n\ndef rounded(value, decimals):\n    return value.quantize(Decimal(1).scaleb(-decimals), rounding=ROUND_HALF_UP)\n\n\ndef evidence_quantity(packet, key):\n    card, inputs = card_of(packet, key)\n    v = fact_numbers(card)\n    q, err, concl = card['quantity'], card['error'], card['conclusions']\n    right = quantity(q['kind'], q['args'], v, inputs, card)\n    wrong = quantity(err['kind'], err['args'], v, inputs, card)\n    dec, tol = q['decimals'], Decimal(q['tolerance'])\n    need(abs(right - wrong) >= Decimal(q['min_separation']), 'Mistake value within the separation of the correct value')\n    unit = UNIT_TEXT[q['unit']]\n    pattern = re.compile(r'^%s (-?\\d+\\.\\d{%d})%s\\. (.+)$' % (re.escape(q['label']), dec, re.escape(unit)))\n    texts = {concl['paper']['text']: 'paper', concl['rejected']['text']: 'rejected'}\n    parsed = []\n    for o in packet['options']:\n        m = pattern.match(o['value'])\n        need(m is not None, 'Option %s is not \"label value unit. conclusion\"' % o['label'])\n        need(m.group(2) in texts, 'Option %s conclusion is not on the card' % o['label'])\n        parsed.append((o['label'], Decimal(m.group(1)), texts[m.group(2)]))\n    shown = sorted({p[1] for p in parsed})\n    need(len(shown) == 2 and {(p[1], p[2]) for p in parsed} == {(s, c) for s in shown for c in ('paper', 'rejected')},\n         'Options are not the four value × conclusion combinations')\n    near = [p for p in parsed if abs(p[1] - right) <= tol]\n    need(len({p[1] for p in near}) == 1 and near[0][1] == rounded(right, dec), 'Recomputed value is not shown correctly rounded')\n    other = [s for s in shown if s != near[0][1]][0]\n    need(abs(other - rounded(wrong, dec)) <= tol, 'Second value is not the registered mistake')\n    hits = [p[0] for p in near if p[2] == 'paper']\n    need(len(hits) == 1 and key['correct_label'] == hits[0], 'Key label disagrees with value and conclusion')\n    return dict(label=hits[0], recomputed=str(rounded(right, dec)), mistake=str(rounded(wrong, dec)),\n                parameters=dict(card=card['id'], kind=q['kind']), method='Decimal recomputation from the hashed card; 2×2 option structure')\n\n\ndef evidence_elimination(packet, key):\n    card, inputs = card_of(packet, key)\n    observed = {}\n    for f in card['facts']:\n        for k, val in f.get('observed', {}).items():\n            need(k not in observed, 'Observation stated twice: ' + k)\n            observed[k] = (val, f['id'])\n    by_text = {h['text']: h for h in card['hypotheses']}\n    need(len(by_text) == 4 and {o['value'] for o in packet['options']} == set(by_text), 'Options are not the four card explanations')\n    alive = []\n    for o in packet['options']:\n        h = by_text[o['value']]\n        clash = []\n        for k, val in h['predicts'].items():\n            need(k in observed, 'Prediction %s is not tested by any fact' % k)\n            if observed[k][0] != val:\n                clash.append(observed[k][1])\n        if not clash:\n            alive.append((o['label'], h))\n    need(len(alive) == 1, '%d explanations survive the evidence (need exactly 1)' % len(alive))\n    label, h = alive[0]\n    need(h.get('paper_conclusion') is True, 'The surviving explanation is not the paper conclusion')\n    need(key['correct_label'] == label, 'Key label disagrees with the elimination')\n    return dict(label=label, parameters=dict(card=card['id'], observations=len(observed)),\n                method='predictions compared with observations from the hashed card; single survivor')\n\n\nCHECKERS = {'evidence_quantity': evidence_quantity, 'evidence_elimination': evidence_elimination}\n",
  "checkers/families.py": "\"\"\"One independent checker per task family. Each reads the student packet (what the\nmodel sees) and the answer key, re-derives the task parameters from the question text,\nrecomputes with a different formula than the generator, and verifies all four options.\nA parameter that cannot be read from the question text is a failure: the question is\nthen not answerable from its own text.\n\"\"\"\nimport json\nimport math\nimport re\nfrom decimal import Decimal, localcontext\nfrom . import cells\nfrom .common import (CheckError, need, find, read_xyz, dist, vec, dot, cross, verify_hashes,\n                     judge_numeric, LABELS)\n\n# Covalent radii (Cordero et al. 2008) for the checker's own bonding rule.\nRADII = {'H': 0.31, 'C': 0.76, 'N': 0.71, 'O': 0.66, 'S': 1.05, 'Cl': 1.02, 'P': 1.07, 'F': 0.57,\n         'Si': 1.11, 'Br': 1.20, 'I': 1.39}     # covalent radii, Cordero et al., Dalton Trans. 2008\n\n\ndef inputs_by_name(packet):\n    return {i['name']: i['text'] for i in packet['inputs']}\n\n\n# ---------------------------------------------------------------- perception\ndef named_bond_angle(packet, key):\n    \"\"\"Law of cosines on three interatomic distances (generator: vector dot product).\"\"\"\n    q = packet['question']\n    rows = re.findall(r'([\\w\\-]+) = row (\\d+)', q)\n    need(len(rows) == 3, 'Question must map exactly three named atoms to XYZ rows')\n    vertex = find(r'bond angle at ([\\w\\-]+)', q, 'Question does not name the angle vertex').group(1)\n    names = [n for n, _ in rows]\n    need(vertex == names[1], 'Named vertex is not the middle atom of the listed triple')\n    [text] = [i['text'] for i in packet['inputs'] if i['format'] == 'xyz']\n    atoms = read_xyz(text)\n    need(all(1 <= int(r) <= len(atoms) for _, r in rows), 'Row index outside the XYZ')\n    a, v, b = [atoms[int(r) - 1] for _, r in rows]\n    for end in (a, b):\n        limit = 1.25 * (RADII[end[0]] + RADII[v[0]])\n        need(float(dist(end[1], v[1])) <= limit, 'Named end atom is not bonded to the vertex')\n    va, vb, ab = dist(v[1], a[1]), dist(v[1], b[1]), dist(a[1], b[1])\n    with localcontext() as ctx:\n        ctx.prec = 40\n        cosine = (va * va + vb * vb - ab * ab) / (2 * va * vb)\n    angle = math.degrees(math.acos(max(-1.0, min(1.0, float(cosine)))))\n    verify_hashes(key)\n    return dict(judge_numeric(packet, key, angle), parameters=dict(atoms=rows, vertex=vertex),\n                method='law of cosines from three Decimal distances')\n\n\ndef _pdb_atoms(text):\n    atoms = {}\n    for line in text.splitlines():\n        if line.startswith('ATOM'):\n            need(line[16] == ' ', 'Alternate location in excerpt')\n            atoms[(line[12:16].strip(), int(line[22:26]))] = tuple(Decimal(line[c:c + 8]) for c in (30, 38, 46))\n    return atoms\n\n\ndef backbone_torsion(packet, key):\n    \"\"\"Normals' angle via acos, sign from (n1 x n2).b2 (generator: two atan2 forms).\"\"\"\n    q = packet['question']\n    spec = find(r'defined by atoms ((?:[A-Z0-9]+\\(\\d+\\)–){3}[A-Z0-9]+\\(\\d+\\))', q,\n                'Question does not define the four torsion atoms').group(1)\n    parts = [re.fullmatch(r'([A-Z0-9]+)\\((\\d+)\\)', p).groups() for p in spec.split('–')]\n    need('IUPAC' in q, 'Sign convention not stated')\n    [text] = [i['text'] for i in packet['inputs'] if i['format'] == 'pdb-excerpt']\n    atoms = _pdb_atoms(text)\n    pts = []\n    for name, residue in parts:\n        need((name, int(residue)) in atoms, 'Torsion atom %s(%s) missing from excerpt' % (name, residue))\n        pts.append(atoms[(name, int(residue))])\n    b1, b2, b3 = vec(pts[0], pts[1]), vec(pts[1], pts[2]), vec(pts[2], pts[3])\n    n1, n2 = cross(b1, b2), cross(b2, b3)\n    cosine = dot(n1, n2) / math.sqrt(dot(n1, n1) * dot(n2, n2))\n    angle = math.degrees(math.acos(max(-1.0, min(1.0, cosine))))\n    if dot(cross(n1, n2), b2) < 0:\n        angle = -angle\n    # Provenance: every excerpt line must occur verbatim in the public PDB file.\n    paths = verify_hashes(key)\n    if paths:     # check() requires a recorded source for every real instance\n        source = set(line.rstrip() for p in paths.values() for line in p.read_text(encoding='utf-8').splitlines())\n        need(all(line in source for line in text.splitlines() if line.startswith('ATOM')),\n             'Excerpt lines are not copied unchanged from the source PDB')\n    return dict(judge_numeric(packet, key, angle, period=Decimal(360)), parameters=dict(atoms=spec),\n                method='acos of plane normals with triple-product sign')\n\n\ndef extent(packet, key):\n    \"\"\"Decimal recomputation: Dmax by squared distances, Rg by centroid (explicit sums).\"\"\"\n    q = packet['question']\n    [text] = [i['text'] for i in packet['inputs'] if i['format'] == 'xyz']\n    atoms = read_xyz(text)\n    pts = [p for _, p in atoms]\n    need('mass weights' not in q or 'Do not use mass weights' in q, 'Weighting ambiguous')\n    with localcontext() as ctx:\n        ctx.prec = 40\n        if 'maximum Euclidean distance' in q:\n            best = max(sum((a - b) ** 2 for a, b in zip(p, r)) for i, p in enumerate(pts) for r in pts[i + 1:])\n            value, kind = best.sqrt(), 'max_pair_distance'\n        elif 'radius of gyration' in q:\n            n = len(pts)\n            c = [sum(p[k] for p in pts) / n for k in range(3)]\n            value, kind = (sum(sum((p[k] - c[k]) ** 2 for k in range(3)) for p in pts) / n).sqrt(), 'equal_weight_rg'\n        else:\n            raise CheckError('Question does not state which size measure is asked')\n    verify_hashes(key)\n    return dict(judge_numeric(packet, key, value), parameters=dict(measure=kind, atoms=len(pts)),\n                method='Decimal (40 digits) explicit sums')\n\n\n# ---------------------------------------------------------------- inference\ndef force_path(packet, key):\n    \"\"\"dE/dlambda at B = -(path direction) . F(B), summed atom by atom in Decimal.\"\"\"\n    q = packet['question']\n    need('F_i = −∂E/∂r_i' in q, 'Force–gradient relation not stated in the question')\n    if 'starts at B and moves toward A' in q and 'r_i(B) + λ[r_i(A) − r_i(B)]' in q:\n        sign, direction = -1, 'B_to_A'\n    elif 'r_i(A) + λ[r_i(B) − r_i(A)]' in q and 'at λ = 1' in q:\n        sign, direction = 1, 'A_to_B'\n    else:\n        raise CheckError('Path direction not stated unambiguously')\n    files = inputs_by_name(packet)\n    need({'A.xyz', 'B.xyz', 'forces_B.txt'} <= set(files), 'Missing A, B or force table')\n    a, b = read_xyz(files['A.xyz']), read_xyz(files['B.xyz'])\n    rows = [line.split() for line in files['forces_B.txt'].splitlines()[1:] if line.strip()]\n    need(len(a) == len(b) == len(rows), 'A, B and forces differ in atom count')\n    need([e for e, _ in a] == [e for e, _ in b] == [r[1] for r in rows], 'Atom order differs')\n    need([int(r[0]) for r in rows] == list(range(1, len(rows) + 1)), 'Force rows not numbered 1..N')\n    with localcontext() as ctx:\n        ctx.prec = 40\n        projection = sum(Decimal(f) * (pb - pa) for (_, ra), (_, rb), r in zip(a, b, rows)\n                         for pa, pb, f in zip(ra, rb, r[2:]))\n        value = -sign * projection\n    # Provenance: coordinates and forces agree with the public asset to printing precision.\n    [path] = verify_hashes(key).values()\n    data = json.loads(path.read_text())\n    for label, atoms, ref in (('A', a, data['reference_xyz']), ('B', b, data['displaced_xyz'])):\n        need(max(abs(float(c) - r) for (_, p), rr in zip(atoms, ref) for c, r in zip(p, rr)) < 1e-7,\n             label + ' coordinates differ from the source asset')\n    need(max(abs(float(f) - r) for row, rr in zip(rows, data['forces_at_displaced']) for f, r in zip(row[2:], rr)) < 1e-6,\n         'Forces differ from the source asset')\n    return dict(judge_numeric(packet, key, value), parameters=dict(direction=direction, atoms=len(a)),\n                method='Decimal atom-by-atom projection')\n\n\ndef extinction(packet, key):\n    \"\"\"Real/imaginary sums with math.fsum; one option must vanish, three clearly not.\"\"\"\n    q = packet['question']\n    weights_text = find(r'\\(((?:[A-Z][a-z]? = \\d+, )*[A-Z][a-z]? = \\d+)\\)', q,\n                        'Scattering weights not stated in the question').group(1)\n    weights = {k: int(v) for k, v in re.findall(r'([A-Z][a-z]?) = (\\d+)', weights_text)}\n    need('Exactly one of the four reflections' in q, 'Uniqueness premise not stated')\n    [text] = [i['text'] for i in packet['inputs'] if i['format'] == 'fractional-cell-table']\n    lines = text.splitlines()\n    params, atoms = cells.parse_table(text)\n    a = None if params else float(find(r'cubic a = ([\\d.]+) angstrom', lines[0], 'Cell parameter missing').group(1))\n    need(all(len(p) == 3 and all(0 <= x < 1 for x in p) for _, p in atoms), 'Fractional coordinates outside [0,1)')\n    need({e for e, _ in atoms} == set(weights), 'Weights do not cover exactly the elements present')\n    total = sum(weights[e] for e, _ in atoms)\n    verdicts = []\n    for o in packet['options']:\n        hkl = [int(x) for x in find(r'^\\((-?\\d+) (-?\\d+) (-?\\d+)\\)$', o['value'], 'Option is not (h k l)').groups()]\n        phase = [2 * math.pi * sum(h * x for h, x in zip(hkl, p)) for _, p in atoms]\n        re_part = math.fsum(weights[e] * math.cos(t) for (e, _), t in zip(atoms, phase))\n        im_part = math.fsum(weights[e] * math.sin(t) for (e, _), t in zip(atoms, phase))\n        verdicts.append((o['label'], o['value'], math.hypot(re_part, im_part) / total))\n    zero = [v for v in verdicts if v[2] <= 1e-6]\n    need(len(zero) == 1, '%d options have |F| = 0 (need exactly 1)' % len(zero))\n    weakest = min(v[2] for v in verdicts if v[2] > 1e-6)\n    need(weakest >= 1e-3, 'A distractor is nearly extinct (|F|/F000 = %.2e)' % weakest)\n    need(key['correct_label'] == zero[0][0], 'Key label %s != recomputed %s' % (key['correct_label'], zero[0][0]))\n    # Provenance: the table must reproduce the public source (cell edge from the CIF,\n    # or every Cartesian row of the published XYZ cell).\n    [path] = verify_hashes(key).values()\n    if params:\n        need(path.suffix == '.cif', 'Non-cubic tables must come from a CIF')\n        cells.same_cell(params, atoms, path)              # own symmetry expansion of the source\n    elif path.suffix == '.cif':\n        cif_a = find(r'_cell_length_a\\s+([\\d.]+)', path.read_text(encoding='utf-8'), 'CIF lacks cell edge').group(1)\n        need(abs(float(cif_a) - a) < 1e-4, 'Cell edge differs from the CIF')\n    else:\n        source = read_xyz(path.read_text(encoding='utf-8-sig'))\n        need(len(source) == len(atoms) and all(e == s_e and max(abs(x * a - float(c)) for x, c in zip(f, sp)) < 1e-5\n                                               for (e, f), (s_e, sp) in zip(atoms, source)),\n             'Fractional table does not reproduce the published cell')\n    return dict(label=zero[0][0], recomputed=zero[0][1], parameters=dict(weights=weights, **(dict(cell=params) if params else dict(a_A=a)), atoms=len(atoms)),\n                options={l: round(r, 8) for l, _, r in verdicts}, weakest_nonzero=round(weakest, 6),\n                method='separate cos/sin sums over the student table')\n\n\n# ---------------------------------------------------------------- design\ndef _bonds(atoms):\n    pts = [p for _, p in atoms]\n    return {(i, j) for i in range(len(pts)) for j in range(i + 1, len(pts))\n            if float(dist(pts[i], pts[j])) <= 1.25 * (RADII[atoms[i][0]] + RADII[atoms[j][0]])}\n\n\ndef _handedness(atoms, bonds):\n    out = {}\n    for i in range(len(atoms)):\n        nb = sorted({b if a == i else a for a, b in bonds if i in (a, b)})\n        if len(nb) == 4:\n            u, v, w = (vec(atoms[i][1], atoms[j][1]) for j in nb[:3])\n            out[i] = dot(cross(u, v), w) > 0\n    return out\n\n\ndef _shape_gap(p, q):\n    pts = range(len(p))\n    diffs = [float(dist(p[i][1], p[j][1]) - dist(q[i][1], q[j][1])) for i in pts for j in pts if i < j]\n    return math.sqrt(math.fsum(d * d for d in diffs) / len(diffs))\n\n\nPOLICY = {'min_energy': ('e_pbe0_mbd_eV', -1, 0.0434), 'max_dipole': ('dipole_eA', 1, 0.10)}\n\n\ndef conformer_selection(packet, key):\n    \"\"\"Constraints from the candidate files themselves; property looked up by matching\n    coordinates in the hash-verified public dataset extract (never by label or id).\"\"\"\n    q = packet['question']\n    if 'lowest total PBE0+MBD energy' in q:\n        goal = 'min_energy'\n    elif 'largest total dipole-moment magnitude' in q:\n        goal = 'max_dipole'\n    else:\n        raise CheckError('Design goal not stated')\n    need('only by rotating about single bonds' in q, 'Allowed modification not stated')\n    files = inputs_by_name(packet)\n    need(set(files) == {'S0.xyz'} | {'candidate_%s.xyz' % l for l in LABELS}, 'Need S0 and four candidates')\n    need(all('Geom-' not in t for t in files.values()), 'Dataset identifiers visible to the model')\n    s0 = read_xyz(files['S0.xyz'])\n    bonds0, hand0 = _bonds(s0), _handedness(s0, _bonds(s0))\n    [path] = verify_hashes(key).values()\n    data = json.loads(path.read_text())\n    prop, sense, margin = POLICY[goal]\n    rows, candidates = [], []\n    for label in LABELS:\n        atoms = read_xyz(files['candidate_%s.xyz' % label])\n        need([e for e, _ in atoms] == [e for e, _ in s0], label + ': atoms or order differ from S0')\n        need(_bonds(atoms) == bonds0, label + ': bonding differs from S0')\n        need(_handedness(atoms, bonds0) == hand0, label + ': configuration at a 4-coordinate centre differs')\n        need(_shape_gap(atoms, s0) > 0.05, label + ': identical to S0 (or its mirror image)')\n        match = [c for c in data['conformers']\n                 if max(abs(float(x) - y) for (_, p), r in zip(atoms, c['xyz']) for x, y in zip(p, r)) < 1e-6]\n        need(len(match) == 1, label + ': no unique dataset structure with these coordinates')\n        candidates.append((label, atoms))\n        rows.append((label, match[0][prop]))\n    for (l1, a1), (l2, a2) in ((x, y) for i, x in enumerate(candidates) for y in candidates[i + 1:]):\n        need(_shape_gap(a1, a2) > 0.05, '%s and %s are the same or mirror conformers' % (l1, l2))\n    ranked = sorted(rows, key=lambda r: sense * r[1], reverse=True)\n    lead = sense * (ranked[0][1] - ranked[1][1])\n    need(lead >= margin, 'Best candidate leads by %.4f, below the %.4f policy margin' % (lead, margin))\n    need(key['correct_label'] == ranked[0][0], 'Key label %s != recomputed %s' % (key['correct_label'], ranked[0][0]))\n    return dict(label=ranked[0][0], recomputed=ranked[0][0], parameters=dict(goal=goal, atoms=len(s0)),\n                options={l: v for l, v in rows}, lead=round(lead, 6), policy_margin=margin,\n                method='own bond graph, handedness and distance-matrix checks; property matched by coordinates')\n\n\nfrom . import stereo as _stereo\nfrom . import migrated as _migrated\nfrom . import superlattice as _superlattice\nfrom . import moire as _moire\nfrom . import hostguest as _hostguest\nfrom . import quantum_dot as _quantum_dot\nfrom . import design_extra as _design_extra\nfrom . import mesoscale as _mesoscale\nfrom . import rotational as _rotational\nfrom . import hbonds as _hbonds\nfrom . import evidence as _evidence\nfrom . import paper_design as _paper_design\n\nCHECKERS = {\n    'stereo_relationship': _stereo.stereo_relationship,\n    'stereo_property_inference': _stereo.stereo_property_inference,\n    'stereo_design_selection': _stereo.stereo_design_selection,\n    'named_bond_angle': named_bond_angle,\n    'backbone_torsion': backbone_torsion,\n    'extent_choice_v2': extent,\n    'force_path_derivative': force_path,\n    'kinematic_extinction': extinction,\n    'conformer_target_selection': conformer_selection,\n    **_migrated.CHECKERS,\n    **_superlattice.CHECKERS,\n    **_moire.CHECKERS,\n    **_hostguest.CHECKERS,\n    **_quantum_dot.CHECKERS,\n    **_design_extra.CHECKERS,\n    **_mesoscale.CHECKERS,\n    **_rotational.CHECKERS,\n    **_hbonds.CHECKERS,\n    **_evidence.CHECKERS,\n    **_paper_design.CHECKERS,\n}\n",
  "checkers/hbonds.py": "\"\"\"Independent checkers for hbond_geometry and hbond_criteria. No generation code is imported.\n\nAtom rows, the asked quantity and the criteria are read from the question; distances use Decimal arithmetic and the\nangle uses the law of cosines (the generator uses vector dot products). Bonding is checked with the checker's own\ncovalent radii; attached XYZ files must equal the hashed source assets.\n\"\"\"\nimport math\nimport re\nfrom decimal import localcontext\nfrom .common import need, find, read_xyz, verify_hashes, judge_numeric, dist\n\nRADII = {'H': 0.31, 'C': 0.76, 'N': 0.71, 'O': 0.66, 'S': 1.05, 'F': 0.57}\nCONTACT = re.compile(r'([A-Z][a-z]?)(\\d+)–([A-Z][a-z]?)(\\d+)···([A-Z][a-z]?)(\\d+)')\n\n\ndef bonded(a, b):\n    return float(dist(a[1], b[1])) <= 1.25 * (RADII[a[0]] + RADII[b[0]])\n\n\ndef geometry(atoms, d, h, a):\n    D, H, A = atoms[d - 1], atoms[h - 1], atoms[a - 1]\n    need(H[0] == 'H' and D[0] in ('N', 'O') and A[0] in ('N', 'O', 'F'), 'Contact atoms have the wrong elements')\n    need(bonded(D, H), 'Donor and hydrogen are not bonded')\n    need(not bonded(H, A), 'Hydrogen is bonded to the acceptor')\n    dh, ha, da = dist(D[1], H[1]), dist(H[1], A[1]), dist(D[1], A[1])\n    with localcontext() as ctx:\n        ctx.prec = 40\n        cos = (dh * dh + ha * ha - da * da) / (2 * dh * ha)\n    return dict(da=da, ha=ha, angle=math.degrees(math.acos(max(-1.0, min(1.0, float(cos))))))\n\n\ndef attached(packet, paths):\n    sources = {p.read_bytes().decode('utf-8-sig') for p in paths.values()}\n    for item in packet['inputs']:\n        need(item['text'] in sources, 'Attached file %s differs from the source assets' % item['name'])\n\n\ndef hbond_geometry(packet, key):\n    q = packet['question']\n    rows = find(r'\\(rows (\\d+), (\\d+) and (\\d+), counted', q, 'Contact rows not stated')\n    d, h, a = (int(x) for x in rows.groups())\n    attached(packet, verify_hashes(key))\n    [item] = packet['inputs']\n    atoms = read_xyz(item['text'])\n    g = geometry(atoms, d, h, a)\n    if 'donor–acceptor distance' in q:\n        value, what = g['da'], 'da'\n    elif 'hydrogen–acceptor distance' in q:\n        value, what = g['ha'], 'ha'\n    else:\n        need('angle at the hydrogen' in q, 'Asked quantity not recognised')\n        value, what = g['angle'], 'angle'\n    return dict(judge_numeric(packet, key, value), parameters=dict(rows=[d, h, a], quantity=what),\n                method='Decimal distances; law of cosines; own covalent-radius bonding check')\n\n\ndef hbond_criteria(packet, key):\n    q = packet['question']\n    crit = find(r'H···A distance ≤ ([\\d.]+) Å and D–H···A angle ≥ ([\\d.]+)°', q, 'Criteria not stated')\n    dmax, amin = float(crit.group(1)), float(crit.group(2))\n    attached(packet, verify_hashes(key))\n    files = {m.group(1): m.group(2) for m in re.finditer(r'conformer (\\w+) = (conformer_\\w+\\.xyz)', q)}\n    texts = {i['name']: i['text'] for i in packet['inputs']}\n    verdicts = {}\n    for o in packet['options']:\n        m = CONTACT.search(o['value'])\n        conf = find(r'in conformer (\\w+)$', o['value'], 'Option does not name a conformer').group(1)\n        need(conf in files and files[conf] in texts, 'Option names an unknown conformer')\n        atoms = read_xyz(texts[files[conf]])\n        d, h, a = int(m.group(2)), int(m.group(4)), int(m.group(6))\n        need((atoms[d - 1][0], atoms[h - 1][0], atoms[a - 1][0]) == (m.group(1), m.group(3), m.group(5)), 'Option atoms do not match the file')\n        g = geometry(atoms, d, h, a)\n        verdicts[o['label']] = (float(g['ha']) <= dmax and g['angle'] >= amin, round(float(g['ha']), 4), round(g['angle'], 2))\n    hits = [l for l, v in verdicts.items() if v[0]]\n    need(len(hits) == 1, 'Exactly one option must meet both criteria (found %d)' % len(hits))\n    need(key['correct_label'] == hits[0], 'Key label %s != recomputed %s' % (key['correct_label'], hits[0]))\n    return dict(label=hits[0], parameters=dict(ha_max=dmax, angle_min=amin, verdicts=verdicts),\n                method='Decimal distances; law of cosines; criteria read from the question')\n\n\nCHECKERS = {'hbond_geometry': hbond_geometry, 'hbond_criteria': hbond_criteria}\n",
  "checkers/hostguest.py": "\"\"\"Independent checker for the SAMPL9 WP6 evidence families (chemistry, 1-10 nm).\nNo generation code is imported. The checker reads the transcribed measurement table named in the answer key\n(hash-verified), confirms that every supplied structure is the published SAMPL9 file for the guest its option\nnames, that the question states the measurement conditions, and re-derives the choice from the measured\nbinding free energies with the same policy margins.\n\"\"\"\nimport json\nimport re\nfrom .common import need, find, verify_hashes\n\nMARGIN = 0.8\nTHRESHOLD_GAP = 0.3\n\n\ndef evidence_and_guests(packet, key):\n    paths = verify_hashes(key)\n    ev_path = [p for rel, p in paths.items() if rel.endswith('WP6-binding.json')]\n    need(len(ev_path) == 1, 'Evidence table not recorded in the key')\n    evidence = json.loads(ev_path[0].read_text(encoding='utf-8'))\n    q = packet['question']\n    need('pH 7.40' in q and '298.15 K' in q and 'isothermal titration calorimetry' in q, 'Measurement conditions not stated')\n    by_name = {p.name: p for p in paths.values()}\n    for inp in packet['inputs']:\n        need(inp['name'] in by_name and by_name[inp['name']].read_bytes() == inp['text'].encode('utf-8'), 'Input is not the published file: ' + inp['name'])\n    guests = []\n    for o in packet['options']:\n        m = re.fullmatch(r'(G\\d+): (.+) \\(WP6-(G\\d+)\\.xyz\\)', o['value'])\n        need(m is not None and m.group(1) == m.group(3), 'Option does not name one guest file')\n        g = m.group(1)\n        need(g in evidence['guests'] and evidence['guests'][g]['name'] == m.group(2), 'Guest name does not match the table')\n        need('WP6-%s.xyz' % g in {i['name'] for i in packet['inputs']}, 'Structure for option guest not supplied')\n        guests.append((o['label'], g))\n    return evidence, guests\n\n\ndef binding_evidence_choice(packet, key):\n    evidence, guests = evidence_and_guests(packet, key)\n    need('most negative measured binding free energy' in packet['question'], 'Criterion not stated')\n    dg = {label: evidence['guests'][g]['DG_kcal_mol'] for label, g in guests}\n    ranked = sorted(dg, key=dg.get)\n    need(dg[ranked[1]] - dg[ranked[0]] >= MARGIN, 'Measured winner does not lead by the margin')\n    need(key['correct_label'] == ranked[0], 'Key label disagrees with the measured ranking')\n    return dict(label=ranked[0], parameters=dict(measured_DG=dg), method='measured ITC ΔG from the SAMPL9 table')\n\n\ndef binding_design_choice(packet, key):\n    evidence, guests = evidence_and_guests(packet, key)\n    q = packet['question']\n    ref = find(r'You start from guest (G\\d+)', q, 'Reference guest not stated').group(1)\n    gain = float(find(r'at least ([\\d.]+) kcal/mol more strongly', q, 'Target gain not stated').group(1))\n    stated = float(find(r'under these conditions is (−?-?[\\d.]+) kcal/mol', q, 'Reference value not stated').group(1).replace('−', '-'))\n    dg0 = evidence['guests'][ref]['DG_kcal_mol']\n    need(abs(stated - dg0) < 1e-9, 'Stated reference ΔG differs from the table')\n    gains = {label: dg0 - evidence['guests'][g]['DG_kcal_mol'] for label, g in guests}\n    need(all(g != ref for _, g in guests), 'Reference guest offered as a candidate')\n    ok = [label for label, v in gains.items() if v >= gain]\n    need(len(ok) == 1, 'Not exactly one candidate meets the target')\n    need(all(abs(v - gain) >= THRESHOLD_GAP for v in gains.values()), 'A candidate sits too close to the threshold')\n    need(key['correct_label'] == ok[0], 'Key label disagrees with the measured data')\n    return dict(label=ok[0], parameters=dict(reference=ref, improvement=gains), method='measured ITC ΔG; design threshold')\n\n\nCHECKERS = {'binding_evidence_choice': binding_evidence_choice, 'binding_design_choice': binding_design_choice}\n",
  "checkers/mesoscale.py": "\"\"\"Independent checkers for the vortex-lattice (quantum) and cholesteric (chemistry) families, 100-1000 nm.\nNo generation code is imported. Vortex maps: the primitive cell is recovered from the coordinates (checkers.moire.moire_cell)\nand density, field, flux and the first Bragg peak follow from the cell area. Director fields: the directors are projected on the\nplane normal to the axis (first to last site), the angle is unwrapped modulo π and fitted linearly; the slope gives the pitch and\nits sign (in a right-handed frame whose third axis points along the travel direction) gives the handedness.\n\"\"\"\nimport math\nimport re\nimport numpy as np\nfrom .common import need, find, verify_hashes, judge_numeric, rounded\nfrom .moire import moire_cell\n\n\ndef same_as_asset(packet, key):\n    by_name = {p.name: p for p in verify_hashes(key).values()}\n    for inp in packet['inputs']:\n        need(inp['name'] in by_name and by_name[inp['name']].read_bytes() == inp['text'].encode('utf-8'), 'Input differs: ' + inp['name'])\n\n\ndef conditions(q, phrase):\n    need('Model conditions:' in q and phrase in q, 'Paper-parameter model conditions not stated')\n\n\n# ------------------------------------------------------------------ vortex lattices\ndef vortex_cell(inp):\n    lines = inp['text'].splitlines()\n    rows = [l.split() for l in lines[2:] if l.strip()]\n    need(lines[0].strip().isdigit() and int(lines[0]) == len(rows) and all(len(r) == 3 and r[0] == 'V' for r in rows), 'Rows must be \"V x y\"')\n    return moire_cell(np.asarray([[float(r[1]), float(r[2])] for r in rows]))\n\n\ndef vortex_quantity(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    conditions(q, 'one superconducting flux quantum per vortex')\n    a, area = vortex_cell(packet['inputs'][0])                 # nm, nm^2 per vortex\n    if 'vortex lattice spacing' in q:\n        value = a\n    elif 'per square micrometre' in q:\n        value = 1e6 / area\n    elif 'magnetic induction B' in q:\n        m = find(r'Φ0 = h/\\(2e\\) = ([\\d.]+) × 10⁻¹⁵ Wb', q, 'Flux quantum not stated')\n        value = float(m.group(1)) * 1e-15 / (area * 1e-18) * 1e3\n    elif 'How much magnetic flux does each vortex carry' in q:\n        b = float(find(r'B = ([\\d.]+) mT', q, 'Field not stated').group(1))\n        value = b * 1e-3 * area * 1e-18 * 1e15\n    else:\n        need('first-order Bragg peak' in q and 'q = 4π sinθ/λ' in q, 'Unknown quantity')\n        value = 2 * math.pi * a / area * 1000                  # |b1| = 2π a / cell area, in um^-1\n    return dict(judge_numeric(packet, key, value), parameters=dict(spacing_nm=a, cell_nm2=area), method='primitive cell from vortex centres')\n\n\ndef vortex_design(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    conditions(q, 'one superconducting flux quantum per vortex')\n    cells = {i['name']: vortex_cell(i) for i in packet['inputs']}\n    field = {}\n    for o in packet['options']:\n        m = re.fullmatch(r'.*\\(([\\d.]+) mT\\) \\((\\S+)\\)', o['value'])\n        need(m is not None and m.group(2) in cells, 'Option does not name a field and a supplied file')\n        field[m.group(2)] = (o['label'], float(m.group(1)))\n    s = re.search(r'spacing is closest to ([\\d.]+) nm', q)\n    k = re.search(r'Bragg peak .* is closest to ([\\d.]+) μm⁻¹', q)\n    d = re.search(r'at least ([\\d.]+) vortices per square micrometre', q)\n    need(sum(x is not None for x in (s, k, d)) == 1, 'Design goal not stated exactly once')\n    if d:\n        t = float(d.group(1))\n        ok = [n for n, (a, area) in cells.items() if 1e6 / area >= t]\n        need(ok, 'No field meets the density')\n        win = min(ok, key=lambda n: field[n][1])\n    else:\n        t = float((s or k).group(1))\n        prop = {n: (a if s else 2 * math.pi * a / area * 1000) for n, (a, area) in cells.items()}\n        ranked = sorted(prop, key=lambda n: abs(prop[n] - t))\n        need(abs(prop[ranked[1]] - t) > abs(prop[ranked[0]] - t) + 1e-6, 'Tie')\n        win = ranked[0]\n    need(key['correct_label'] == field[win][0], 'Key label disagrees with recomputed choice')\n    return dict(label=field[win][0], parameters={n: dict(spacing_nm=c[0]) for n, c in cells.items()}, method='primitive cells; goal rule')\n\n\n# ------------------------------------------------------------------ cholesteric director fields\ndef helix(inp):\n    lines = inp['text'].splitlines()\n    rows = [l.split() for l in lines[2:] if l.strip()]\n    need(lines[0].strip().isdigit() and int(lines[0]) == len(rows) and all(len(r) == 7 and r[0] == 'site' for r in rows), 'Bad director file')\n    pos = np.asarray([[float(v) for v in r[1:4]] for r in rows])\n    n = np.asarray([[float(v) for v in r[4:]] for r in rows])\n    u = pos[-1] - pos[0]\n    length = np.linalg.norm(u)\n    u /= length\n    e1 = n[0] - (n[0] @ u) * u\n    e1 /= np.linalg.norm(e1)\n    e2 = np.cross(u, e1)                                      # (e1, e2, u) right-handed\n    phi = np.arctan2(n @ e2, n @ e1)\n    phi = np.unwrap(2 * phi) / 2                              # director angle is defined modulo π\n    s = (pos - pos[0]) @ u\n    slope = np.polyfit(s, phi, 1)[0]\n    need(np.abs(phi - np.polyval(np.polyfit(s, phi, 1), s)).max() < 1e-6, 'Twist is not uniform')\n    return float(2 * math.pi / abs(slope)), (1 if slope > 0 else -1)\n\n\ndef indices(q):\n    m = re.search(r'ne = ([\\d.]+), no = ([\\d.]+)', q)\n    return (float(m.group(1)), float(m.group(2))) if m else None\n\n\ndef cholesteric_quantity(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    conditions(q, 'the director twists uniformly about a straight helix axis')\n    p, hand = helix(packet['inputs'][0])\n    if 'What are the handedness and the helical pitch' in q:\n        need('right thumb pointing along the direction of travel' in q, 'Handedness rule not stated')\n        want = '%s, pitch %s nm' % ('right-handed' if hand > 0 else 'left-handed', rounded(p, 1))\n        hits = [o['label'] for o in packet['options'] if o['value'] == want]\n        need(len(hits) == 1 and key['correct_label'] == hits[0], 'Key disagrees with recomputed handedness/pitch')\n        return dict(label=hits[0], parameters=dict(pitch_nm=p, hand=hand), method='projected angle fit')\n    if 'What is the helical pitch p' in q:\n        value = p\n    elif 'What is the helical twisting power HTP' in q:\n        c = float(find(r'contains ([\\d.]+) wt% of the chiral dopant', q, 'Concentration not stated').group(1))\n        value = 1000 / (p * c / 100)\n    else:\n        ix = indices(q)\n        if ix:\n            need('(ne + no)/2' in q, 'Index rule not stated')\n            n_avg, dn = sum(ix) / 2, ix[0] - ix[1]\n        else:\n            need('average refractive index 1.6' in q, 'Index not stated')\n            n_avg, dn = 1.6, None\n        if 'central wavelength' in q:\n            value = n_avg * p\n        else:\n            need('width Δλ' in q and dn is not None, 'Unknown optical quantity')\n            value = dn * p\n    return dict(judge_numeric(packet, key, value), parameters=dict(pitch_nm=p, hand=hand), method='projected angle fit')\n\n\ndef cholesteric_design(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    conditions(q, 'the director twists uniformly about a straight helix axis')\n    ix = indices(q)\n    films = {}\n    for inp in packet['inputs']:\n        p, hand = helix(inp)\n        if inp['name'].startswith('clc-E44'):\n            need(ix is not None, 'E44 indices not stated')\n            n_avg = sum(ix) / 2\n        else:\n            need('average refractive index 1.6' in q, 'Coating index not stated')\n            n_avg = 1.6\n        films[inp['name']] = dict(lam=n_avg * p, hand=hand, conc=(float(re.search(r'R5011-([\\d.]+)wt', inp['name']).group(1))\n                                                                   if 'R5011' in inp['name'] else None))\n    labels = {}\n    for o in packet['options']:\n        m = re.search(r'\\((\\S+\\.txt)\\)$', o['value'])\n        need(m is not None and m.group(1) in films, 'Option does not name a supplied file')\n        labels[m.group(1)] = o['label']\n    close = re.search(r'centred as close as possible to ([\\d.]+) nm', q)\n    below = re.search(r'centred at or below ([\\d.]+) nm', q)\n    need((close is None) != (below is None), 'Design goal not stated exactly once')\n    if close:\n        t = float(close.group(1))\n        pool = {k: v for k, v in films.items() if 'helix is left-handed' not in q or v['hand'] < 0}\n        need(pool, 'No candidate has the required handedness')\n        ranked = sorted(pool, key=lambda k: abs(pool[k]['lam'] - t))\n        need(len(ranked) == 1 or abs(pool[ranked[1]]['lam'] - t) > abs(pool[ranked[0]]['lam'] - t) + 1e-6, 'Tie')\n        win = ranked[0]\n    else:\n        t = float(below.group(1))\n        ok = [k for k, v in films.items() if v['lam'] <= t]\n        need(ok and all(films[k]['conc'] is not None for k in ok), 'No candidate meets the limit')\n        win = min(ok, key=lambda k: films[k]['conc'])\n    need(key['correct_label'] == labels[win], 'Key label disagrees with recomputed choice')\n    return dict(label=labels[win], parameters={k: dict(reflection_nm=round(v['lam'], 2), hand=v['hand']) for k, v in films.items()},\n                method='projected angle fit per file; goal rule')\n\n\nCHECKERS = {'vortex_geometry': vortex_quantity, 'vortex_inference': vortex_quantity, 'vortex_design': vortex_design,\n            'cholesteric_geometry': cholesteric_quantity, 'cholesteric_optics': cholesteric_quantity, 'cholesteric_design': cholesteric_design}\n",
  "checkers/migrated.py": "\"\"\"Independent checkers for the families migrated from legacy calculators (roadmap A5).\nNo generation code is imported; parameters are read from the question text.\n\"\"\"\nimport cmath\nimport itertools\nimport math\nimport re\nimport numpy as np\nfrom decimal import Decimal, localcontext\nfrom .common import need, find, read_xyz, verify_hashes, judge_numeric, LABELS\nfrom . import cells\n\nRADII = {'H': 0.31, 'C': 0.76, 'N': 0.71, 'O': 0.66, 'S': 1.05, 'Cl': 1.02, 'P': 1.07, 'F': 0.57,\n         'Si': 1.11, 'Br': 1.20, 'I': 1.39}     # covalent radii, Cordero et al., Dalton Trans. 2008\n\n\ndef dec_dist(p, q):\n    with localcontext() as ctx:\n        ctx.prec = 40\n        return sum((Decimal(str(a)) - Decimal(str(b))) ** 2 for a, b in zip(p, q)).sqrt()\n\n\ndef pdb_atoms(text):\n    out = {}\n    for line in text.splitlines():\n        if line.startswith('ATOM'):\n            out[(line[12:16].strip(), line[17:20].strip().title(), int(line[22:26]))] = tuple(float(line[c:c + 8]) for c in (30, 38, 46))\n    return out\n\n\ndef verbatim(packet_text, key, prefix=('ATOM', 'SSBOND')):\n    [path] = verify_hashes(key).values()\n    source = {l.rstrip() for l in path.read_text(encoding='utf-8').splitlines()}\n    need(all(l in source for l in packet_text.splitlines() if l.startswith(prefix)), 'Excerpt lines not copied unchanged from the source')\n    return path\n\n\n# ------------------------------------------------------------------ bond distance\ndef named_bond_distance(packet, key):\n    q = packet['question']\n    [inp] = packet['inputs']\n    if inp['format'] == 'pdb-excerpt':\n        named = re.findall(r'([A-Z0-9]+)\\(([A-Z][a-z]{2})(\\d+)\\)', q)\n        need(len(named) == 2, 'Question must name exactly two PDB atoms')\n        atoms = pdb_atoms(inp['text'])\n        points = [atoms.get((n, r, int(k))) for n, r, k in named]\n        need(all(points), 'Named atoms missing from excerpt')\n        elements = [n[0] for n, _, _ in named]\n        if 'SSBOND' in q:\n            pair = {int(k) for _, _, k in named}\n            ss = [l for l in inp['text'].splitlines() if l.startswith('SSBOND')]\n            need(any({int(l[17:21]), int(l[31:35])} == pair for l in ss), 'SSBOND record for the named pair missing')\n        verbatim(inp['text'], key)\n    else:\n        named = re.findall(r'(\\w+) \\(row (\\d+)\\)', q)\n        need(len(named) == 2, 'Question must name exactly two atoms by row')\n        rows = read_xyz(inp['text'])\n        picked = [rows[int(r) - 1] for _, r in named]\n        elements, points = [e for e, _ in picked], [p for _, p in picked]\n        need(all(n.startswith(e) for (n, _), e in zip(named, elements)), 'Atom names disagree with XYZ elements')\n        verify_hashes(key)\n    d = dec_dist(*points)\n    need(float(d) <= 1.25 * (RADII[elements[0]] + RADII[elements[1]]), 'Named atoms are not bonded')\n    return dict(judge_numeric(packet, key, d), parameters=dict(atoms=named), method='Decimal distance; own bonding rule')\n\n\n# ------------------------------------------------------------------ crystal\ndef coordination_shell_general(packet, key, q, text):\n    \"\"\"Any crystal system: metric-tensor distances over 125 cells; the table must be the expanded CIF.\"\"\"\n    params, rows = cells.parse_table(text)\n    G = cells.metric(params)\n    centre = [float(x) for x in find(r'at fractional \\(([-\\d.]+), ([-\\d.]+), ([-\\d.]+)\\)', q, 'Centre position missing').groups()]\n    element = find(r'how many ([A-Z][a-z]?) atoms lie at the shortest', q, 'Partner species missing').group(1)\n    at = [f for e, f in rows if max(abs(x - c) for x, c in zip(f, centre)) < 1e-4]\n    need(len(at) == 1, 'No single atom at the stated centre position')\n    centre = at[0]          # the question prints 4 decimals (0.3333); use the tabulated atom itself\n    dists = sorted(d for e, f in rows if e == element for t in itertools.product(range(-2, 3), repeat=3)\n                   for d in [cells.distance(G, centre, [x + s for x, s in zip(f, t)])] if d > 1e-6)\n    d1 = dists[0]\n    n1 = sum(1 for d in dists if d - d1 <= 1e-3)\n    verdicts = []\n    for o in packet['options']:\n        n, d = find(r'^(\\d+) at ([\\d.]+) Å$', o['value'], 'Option must read \"N at D Å\"').groups()\n        verdicts.append(int(n) == n1 and abs(float(d) - d1) <= 0.0005 + 1e-9)\n    need(sum(verdicts) == 1, '%d options match the shortest distance (need exactly 1)' % sum(verdicts))\n    label = LABELS[verdicts.index(True)]\n    need(key['correct_label'] == label, 'Key label %s != recomputed %s' % (key['correct_label'], label))\n    [path] = verify_hashes(key).values()\n    atoms = cells.same_cell(params, rows, path)\n    return dict(label=label, recomputed='%d at %.4f Å' % (n1, d1), parameters=dict(partner=element, cell=params, cif_atoms=atoms),\n                method='metric-tensor neighbour search over 125 cells; own CIF expansion')\n\n\ndef cell_table(packet):\n    [inp] = [i for i in packet['inputs'] if i['format'] == 'fractional-cell-table']\n    lines = inp['text'].splitlines()\n    a = float(find(r'cubic a = ([\\d.]+) angstrom', lines[0], 'Cell edge missing').group(1))\n    rows = [(r[0], [float(x) for x in r[1:]]) for r in (l.split() for l in lines[1:] if l.strip())]\n    return a, rows\n\n\ndef periodic_dists(a, centre, pts, images=True):\n    out = []\n    for f in pts:\n        for t in (itertools.product((-1, 0, 1), repeat=3) if images else [(0, 0, 0)]):\n            d = a * math.sqrt(sum((x + s - c) ** 2 for x, s, c in zip(f, t, centre)))\n            if d > 1e-6:\n                out.append(d)\n    return sorted(out)\n\n\ndef coordination_shell(packet, key):\n    q = packet['question']\n    need('infinite and periodic' in q, 'Periodicity not stated')\n    [text] = [i['text'] for i in packet['inputs'] if i['format'] == 'fractional-cell-table']\n    if cells.parse_table(text)[0]:\n        return coordination_shell_general(packet, key, q, text)\n    a, rows = cell_table(packet)\n    centre = [float(x) for x in find(r'at fractional \\(([-\\d.]+), ([-\\d.]+), ([-\\d.]+)\\)', q, 'Centre position missing').groups()]\n    part = find(r'how many (other )?(μ4-)?([A-Z][a-z]?) atoms', q, 'Partner species missing')\n    element, mu4 = part.group(3), bool(part.group(2))\n\n    def is_node(f):     # an O with four Zn within 2.4 angstrom, periodic images included\n        return sum(1 for d in periodic_dists(a, f, [g for e, g in rows if e == 'Zn']) if d <= 2.4) == 4\n\n    partners = [f for e, f in rows if e == element and (not mu4 or is_node(f))]\n    at = [f for e, f in rows if max(abs(x - c) for x, c in zip(f, centre)) < 1e-4]\n    need(len(at) == 1, 'No single atom at the stated centre position')\n    centre = at[0]          # the question prints 4 decimals; in a 26 A cell that alone shifts distances by ~1e-3 A\n    dists = periodic_dists(a, centre, partners)\n    d1 = dists[0]\n    n1 = sum(1 for d in dists if d - d1 <= 1e-3)\n    verdicts = []\n    for o in packet['options']:\n        n, d = find(r'^(\\d+) at ([\\d.]+) Å$', o['value'], 'Option must read \"N at D Å\"').groups()\n        verdicts.append(int(n) == n1 and abs(float(d) - d1) <= 0.0005 + 1e-9)\n    need(sum(verdicts) == 1, '%d options match the nearest shell (need exactly 1)' % sum(verdicts))\n    label = LABELS[verdicts.index(True)]\n    need(key['correct_label'] == label, 'Key label %s != recomputed %s' % (key['correct_label'], label))\n    verify_hashes(key)\n    return dict(label=label, recomputed='%d at %.4f Å' % (n1, d1), parameters=dict(partner=element, mu4_node=mu4),\n                method='own periodic neighbour search over 27 cells')\n\n\ndef first_diffraction_peak(packet, key):\n    q = packet['question']\n    weights = {k: int(v) for k, v in re.findall(r'([A-Z][a-z]?) = (\\d+)', find(r'weights \\(([^)]*)\\)', q, 'Weights missing').group(1))}\n    lam = float(find(r'wavelength ([\\d.]+) Å', q, 'Wavelength missing').group(1))\n    [text] = [i['text'] for i in packet['inputs'] if i['format'] == 'fractional-cell-table']\n    params, general_rows = cells.parse_table(text)\n    if params:\n        # Any crystal system: every (h k l) with |h|, |k|, |l| <= 5 (one more than the generator searches).\n        need({e for e, _ in general_rows} == set(weights), 'Weights must cover the elements present')\n        Ginv = np.linalg.inv(cells.metric(params))\n        total = sum(weights[e] for e, _ in general_rows)\n        best = None\n        for hkl in itertools.product(range(-5, 6), repeat=3):\n            if hkl == (0, 0, 0):\n                continue\n            s = lam / (2 * cells.d_spacing(Ginv, hkl))\n            if s > 1:\n                continue\n            f = abs(sum(weights[e] * cmath.exp(2j * math.pi * (hkl[0] * x + hkl[1] * y + hkl[2] * z)) for e, (x, y, z) in general_rows)) / total\n            if f > 1e-6 and (best is None or s < best[0] - 1e-12):\n                best = (s, hkl)\n        [path] = verify_hashes(key).values()\n        atoms = cells.same_cell(params, general_rows, path)\n        return dict(judge_numeric(packet, key, 2 * math.degrees(math.asin(best[0]))),\n                    parameters=dict(weights=weights, wavelength_A=lam, reflection=best[1], cell=params, cif_atoms=atoms),\n                    method='metric-tensor d-spacings, all (h k l) within ±5, own structure-factor sum; own CIF expansion')\n    a, rows = cell_table(packet)\n    need({e for e, _ in rows} == set(weights), 'Weights must cover the elements present')\n    total = sum(weights[e] for e, _ in rows)\n    best = None\n    for h, k, l in itertools.product(range(6), repeat=3):\n        if (h, k, l) == (0, 0, 0):\n            continue\n        s = lam * math.sqrt(h * h + k * k + l * l) / (2 * a)\n        if s > 1:\n            continue\n        f = abs(sum(weights[e] * cmath.exp(2j * math.pi * (h * x + k * y + l * z)) for e, (x, y, z) in rows)) / total\n        if f > 1e-6 and (best is None or s < best[0] - 1e-12):\n            best = (s, (h, k, l))\n    angle = 2 * math.degrees(math.asin(best[0]))\n    verify_hashes(key)\n    return dict(judge_numeric(packet, key, angle), parameters=dict(weights=weights, wavelength_A=lam, reflection=best[1]),\n                method='all (h k l) up to 5 with own structure-factor sum')\n\n\n# ------------------------------------------------------------------ scattering\ndef fret_efficiency(packet, key):\n    q = packet['question']\n    sites = re.findall(r\"atom (\\S+) of (?:nucleotide )?([A-Z][a-z]{0,2})(\\d+)\", q)\n    need(len(sites) == 2, 'Donor and acceptor atoms must be named')\n    r0 = float(find(r'R0 = ([\\d.]+) nm', q, 'Foerster radius missing').group(1))\n    [inp] = packet['inputs']\n    atoms = pdb_atoms(inp['text'])\n    pts = [atoms.get((n, r, int(k))) for n, r, k in sites]\n    need(all(pts), 'Donor or acceptor atom missing from excerpt')\n    verbatim(inp['text'], key)\n    r = float(dec_dist(*pts)) / 10\n    e = 1 / (1 + (r / r0) ** 6)\n    return dict(judge_numeric(packet, key, e), parameters=dict(sites=sites, R0_nm=r0, r_nm=r), method='straight-line distance; Foerster law')\n\n\ndef guinier_intensity(packet, key):\n    q = packet['question']\n    qv = float(find(r'q = ([\\d.]+) nm', q, 'q missing').group(1))\n    need('identical point scatterer' in q, 'Scatterer model not stated')\n    [inp] = packet['inputs']\n    if inp['format'] == 'centroid-table':      # labelled point table: every row is one scatterer\n        pts = [tuple(float(x) for x in l.split()[2:5]) for l in inp['text'].splitlines()[1:] if l.strip()]\n    else:\n        pts = [tuple(float(c) for c in p) for _, p in read_xyz(inp['text'])]\n    n = len(pts)\n    # Pair identity Rg^2 = sum_{i<j} d_ij^2 / N^2 (the generator uses the centroid form); chunked numpy for large N.\n    arr = np.asarray(pts)\n    s = math.fsum(float((((arr[i:i + 500, None, :] - arr[None, :, :]) ** 2).sum(axis=2)).sum()) for i in range(0, n, 500)) / 2\n    rg = math.sqrt(s) / n / 10\n    need(qv * rg <= 1.3, 'q*Rg above the Guinier validity limit')\n    [path] = verify_hashes(key).values()\n    if path.suffix in ('.xyz', '.txt'):   # reduced assembly asset: the input must be that file verbatim\n        need(path.read_bytes() == inp['text'].encode('utf-8'), 'XYZ differs from the published reduced asset')\n        return dict(judge_numeric(packet, key, math.exp(-(qv * rg) ** 2 / 3)), parameters=dict(q_per_nm=qv, rg_nm=rg, atoms=n),\n                    method='pair-distance Rg; Guinier law')\n    # Provenance: the XYZ must be exactly the non-hydrogen main-altloc ATOM records of the named chains.\n    chains = find(r'chains ([A-Z]+)\\)', q, 'Chains missing').group(1)\n    src = [tuple(float(l[c:c + 8]) for c in (30, 38, 46)) for l in path.read_text(encoding='utf-8').split('ENDMDL')[0].splitlines()\n           if l.startswith('ATOM') and l[21] in chains and l[16] in ' A' and (l[76:78].strip() or l[12:16].strip()[0]).upper() != 'H']\n    need(len(src) == n and max(abs(x - y) for p, s2 in zip(pts, src) for x, y in zip(p, s2)) < 1e-6,\n         'XYZ does not reproduce the source heavy atoms')\n    return dict(judge_numeric(packet, key, math.exp(-(qv * rg) ** 2 / 3)), parameters=dict(q_per_nm=qv, rg_nm=rg, atoms=n),\n                method='pair-distance Rg; Guinier law')\n\n\nCHECKERS = {'named_bond_distance': named_bond_distance, 'coordination_shell': coordination_shell,\n            'first_diffraction_peak': first_diffraction_peak, 'fret_efficiency': fret_efficiency,\n            'guinier_intensity': guinier_intensity}\n\n\n# ------------------------------------------------------------------ large assemblies\ndef assembly_points(packet, key):\n    [inp] = packet['inputs']\n    [path] = verify_hashes(key).values()\n    need(path.read_bytes() == inp['text'].encode('utf-8'), 'Input differs from the published reduced asset')\n    if inp['format'] == 'xyz':\n        rows = read_xyz(inp['text'])\n        return [e for e, _ in rows], np.asarray([[float(c) for c in p] for _, p in rows])\n    rows = [l.split() for l in inp['text'].splitlines()[1:] if l.strip()]\n    return [r[0] for r in rows], np.asarray([[float(x) for x in r[2:5]] for r in rows])\n\n\ndef selection(packet, key):\n    labels, pts = assembly_points(packet, key)\n    m = re.search(r'Select all points labelled (\\S+?)\\.', packet['question'])\n    if m:\n        pts = pts[[l == m.group(1) for l in labels]]\n    else:\n        need('Select all supplied points' in packet['question'], 'Point selection not stated')\n    need(len(pts) >= 2, 'Selection is empty')\n    return pts\n\n\ndef assembly_extent(packet, key):\n    pts = selection(packet, key)\n    best, pair = -1.0, None\n    for i in range(0, len(pts), 700):                # own chunking; Decimal on the winning pair\n        d2 = ((pts[i:i + 700, None, :] - pts[None, :, :]) ** 2).sum(axis=2)\n        k = int(d2.argmax())\n        if d2.flat[k] > best:\n            best, pair = float(d2.flat[k]), (i + k // len(pts), k % len(pts))\n    d = dec_dist(pts[pair[0]].tolist(), pts[pair[1]].tolist()) / 10\n    return dict(judge_numeric(packet, key, d), parameters=dict(points=len(pts)), method='chunked brute force + Decimal pair')\n\n\ndef assembly_rg(packet, key):\n    pts = selection(packet, key)\n    n = len(pts)\n    s = math.fsum(float((((pts[i:i + 500, None, :] - pts[None, :, :]) ** 2).sum(axis=2)).sum()) for i in range(0, n, 500)) / 2\n    return dict(judge_numeric(packet, key, math.sqrt(s) / n / 10), parameters=dict(points=n), method='pair-distance identity')\n\n\ndef capsid_architecture(packet, key):\n    q = packet['question']\n    labels, _ = assembly_points(packet, key)\n    trimer = re.search(r'major capsid protein (\\S+) forms trimeric pseudo-hexameric capsomers', q)\n    if trimer:\n        need('12 pentamers at the vertices are formed by a different protein' in q, 'Penton composition not stated')\n        n = sum(1 for l in labels if l == trimer.group(1))\n        need(n > 0 and n % 30 == 0, 'Copy number is not 30(T-1)')\n        t = n // 3 // 10 + 1                           # trimers = 10(T-1)\n        need('triangulation number' in q, 'Unknown architecture question')\n        return dict(judge_numeric(packet, key, t), parameters=dict(component=trimer.group(1), copies=n, T=t),\n                    method='count copies; trimeric capsomers = 10(T-1)')\n    component = find(r'shell formed by (\\S+?)\\?', q, 'Shell component not stated').group(1)\n    n = sum(1 for l in labels if l == component)\n    need(n > 0 and n % 60 == 0, 'Copy number is not a multiple of 60')\n    t = n // 60\n    if 'triangulation number' in q:\n        value = t\n    elif 'hexameric capsomers' in q:\n        value = 10 * (t - 1)\n    else:\n        need('total number of capsomers' in q, 'Unknown architecture question')\n        value = 12 + 10 * (t - 1)\n    return dict(judge_numeric(packet, key, value), parameters=dict(component=component, copies=n, T=t),\n                method='count copies; Caspar–Klug relations')\n\n\nCHECKERS.update(assembly_extent=assembly_extent, assembly_rg=assembly_rg, capsid_architecture=capsid_architecture)\n\n\n# ------------------------------------------------------------------ whole-particle scattering\n# The generator uses the Debye pair sum. Here the orientation average of |sum_j exp(i q.r_j)|^2 is\n# integrated directly over directions with a product Gauss-Legendre (cos theta) x uniform (phi)\n# rule whose degree exceeds q * (particle diameter) + 30, where the plane-wave expansion has converged.\ndef orientation_average(pts_nm, q):\n    centred = pts_nm - pts_nm.mean(axis=0)\n    degree = int(q * 2 * np.sqrt((centred ** 2).sum(axis=1)).max()) + 30\n    x, w = np.polynomial.legendre.leggauss(degree // 2 + 2)\n    phi = 2 * np.pi * np.arange(degree + 2) / (degree + 2)\n    s = np.sqrt(1 - x ** 2)\n    dirs = np.stack([np.outer(s, np.cos(phi)).ravel(), np.outer(s, np.sin(phi)).ravel(), np.repeat(x, len(phi))], axis=1)\n    weights = np.repeat(w, len(phi)) / 2 / len(phi)\n    total = 0.0\n    for i in range(0, len(dirs), 256):\n        amp = np.exp(1j * q * (dirs[i:i + 256] @ centred.T)).sum(axis=1)\n        total += math.fsum(weights[i:i + 256] * np.abs(amp) ** 2)\n    return total / len(pts_nm) ** 2\n\n\ndef scattering_points(packet, key):\n    q = packet['question']\n    need('identical point scatterer' in q, 'Scatterer model not stated')\n    need('q = 4π sinθ/λ' in q, 'q convention not stated')\n    return selection(packet, key) / 10\n\n\ndef debye_intensity(packet, key):\n    pts = scattering_points(packet, key)\n    qv = float(find(r'at q = ([\\d.]+) nm⁻¹', packet['question'], 'q missing').group(1))\n    value = orientation_average(pts, qv)\n    return dict(judge_numeric(packet, key, value), parameters=dict(q_per_nm=qv, points=len(pts)),\n                method='direct orientation average (Gauss-Legendre x uniform phi quadrature)')\n\n\ndef scattering_q_design(packet, key):\n    pts = scattering_points(packet, key)\n    target = float(find(r'first falls to ([\\d.]+)\\.', packet['question'], 'Target intensity missing').group(1))\n    centred = pts - pts.mean(axis=0)\n    rg = math.sqrt(float((centred ** 2).sum(axis=1).mean()))\n    f = lambda q: orientation_average(pts, q) - target\n    # Own search: march in steps of 0.013/Rg from q = 0 to the first sign change, then regula falsi (Illinois).\n    step, lo, flo = 0.013 / rg, 0.0, 1.0 - target\n    need(flo > 0, 'Target must be below I(0)/I(0) = 1')\n    hi = step\n    while f(hi) > 0:\n        lo, hi = hi, hi + step\n        need(hi * rg < 12, 'No crossing found below q*Rg = 12')\n    flo, fhi, side = f(lo), f(hi), 0\n    for _ in range(100):\n        mid = (lo * fhi - hi * flo) / (fhi - flo)\n        fm = f(mid)\n        if abs(fm) < 1e-13 or hi - lo < 1e-12:\n            break\n        if fm > 0:\n            lo, flo = mid, fm\n            fhi, side = (fhi / 2, 1) if side == 1 else (fhi, 1)\n        else:\n            hi, fhi = mid, fm\n            flo, side = (flo / 2, -1) if side == -1 else (flo, -1)\n    return dict(judge_numeric(packet, key, mid), parameters=dict(target=target, rg_nm=rg, points=len(pts)),\n                method='orientation-average quadrature; march + Illinois regula falsi')\n\n\nCHECKERS.update(debye_intensity=debye_intensity, scattering_q_design=scattering_q_design)\n\n\n# ------------------------------------------------------------------ secondary structure from phi/psi\ndef _dihedral(p0, p1, p2, p3):\n    \"\"\"Signed dihedral from plane normals: acos for the magnitude, triple product for the sign.\"\"\"\n    b1, b2, b3 = np.subtract(p1, p0), np.subtract(p2, p1), np.subtract(p3, p2)\n    n1, n2 = np.cross(b1, b2), np.cross(b2, b3)\n    angle = math.degrees(math.acos(max(-1.0, min(1.0, float(np.dot(n1, n2) / (np.linalg.norm(n1) * np.linalg.norm(n2)))))))\n    return -angle if float(np.dot(np.cross(n1, n2), b2)) < 0 else angle\n\n\ndef secondary_structure(packet, key):\n    q = packet['question']\n    need('IUPAC' in q and '360° periodicity' in q, 'Sign convention or periodic distance not stated')\n    m = find(r'dihedrals φ and ψ of ([A-Z][a-z]{2})(\\d+)', q, 'Residue not named')\n    n = int(m.group(2))\n    refs = [(name.strip(), float(a.replace('−', '-')), float(b.replace('−', '-')))\n            for name, a, b in re.findall(r'([\\w\\- α-ωΑ-Ω]+?) \\(φ ([+−-]?\\d+)°, ψ ([+−-]?\\d+)°\\)', q)]\n    refs = [(name.split(': ')[-1].lstrip(', '), a, b) for name, a, b in refs]\n    need(len(refs) == 4, 'Expected four reference conformations')\n    [inp] = packet['inputs']\n    atoms = {}\n    for line in inp['text'].splitlines():\n        if line.startswith('ATOM'):\n            atoms[(line[12:16].strip(), int(line[22:26]))] = tuple(float(line[c:c + 8]) for c in (30, 38, 46))\n    for a in (('C', n - 1), ('N', n), ('CA', n), ('C', n), ('N', n + 1)):\n        need(a in atoms, 'Backbone atom %s(%d) missing' % a)\n    phi = _dihedral(atoms[('C', n - 1)], atoms[('N', n)], atoms[('CA', n)], atoms[('C', n)])\n    psi = _dihedral(atoms[('N', n)], atoms[('CA', n)], atoms[('C', n)], atoms[('N', n + 1)])\n    wrap = lambda x: (x + 180) % 360 - 180\n    dist = {name: math.hypot(wrap(phi - a), wrap(psi - b)) for name, a, b in refs}\n    best = min(dist, key=dist.get)\n    need(sorted(dist.values())[1] - dist[best] > 5, 'Nearest reference not decisive')\n    need(sorted(o['value'] for o in packet['options']) == sorted(dist), 'Options are not exactly the reference conformations')\n    hits = [o['label'] for o in packet['options'] if o['value'] == best]\n    need(key['correct_label'] == hits[0], 'Key label disagrees with recomputed class')\n    # Provenance and evidence: excerpt lines verbatim; the entry's HELIX/SHEET record must agree with the class.\n    [path] = verify_hashes(key).values()\n    source = path.read_text(encoding='utf-8').splitlines()\n    lines = set(l.rstrip() for l in source)\n    need(all(l in lines for l in inp['text'].splitlines() if l.startswith('ATOM')), 'Excerpt lines are not copied unchanged')\n    chain = inp['text'].splitlines()[0][21]\n    kinds = {l[:5] for l in source if (l.startswith('HELIX') and l[19] == chain and int(l[21:25]) <= n <= int(l[33:37]))\n             or (l.startswith('SHEET') and l[21] == chain and int(l[22:26]) <= n <= int(l[33:37]))}\n    need(kinds in ({'HELIX'}, {'SHEET'}), 'No unique HELIX/SHEET record for the residue')\n    need(('α-helix' in best and 'right' in best) if kinds == {'HELIX'} else best == 'β-strand', 'Class disagrees with the entry record')\n    return dict(label=hits[0], parameters=dict(phi=phi, psi=psi, distances=dist, record=sorted(kinds)[0]),\n                method='acos dihedrals; nearest reference; HELIX/SHEET evidence')\n\n\nCHECKERS.update(secondary_structure=secondary_structure)\n",
  "checkers/moire.py": "\"\"\"Independent checkers for the twisted-bilayer-graphene moire families (quantum, 10-100 nm).\nNo generation code is imported. AA maps: primitive vectors are chosen from the nearest-neighbour vectors\nand every site must be an integer combination of them; the cell area is their cross product (no sqrt(3)/2\nformula). Atomistic patch: each layer's orientation comes from a six-fold phase average of its lattice\nvectors (second neighbours), and the lattice constant from their length.\n\"\"\"\nimport cmath\nimport math\nimport re\nimport numpy as np\nfrom .common import need, find, read_xyz, verify_hashes, judge_numeric\n\nTOL = 1e-5\n\n\ndef same_as_asset(packet, key):\n    by_name = {p.name: p for p in verify_hashes(key).values()}\n    for inp in packet['inputs']:\n        need(inp['name'] in by_name and by_name[inp['name']].read_bytes() == inp['text'].encode('utf-8'),\n             'Input differs from the published model: ' + inp['name'])\n\n\ndef aa_sites(inp):\n    lines = inp['text'].splitlines()\n    rows = [l.split() for l in lines[2:] if l.strip()]\n    need(lines[0].strip().isdigit() and int(lines[0]) == len(rows), 'Map count invalid')\n    need(all(len(r) == 3 and r[0] == 'AA' for r in rows), 'Rows must be \"AA x y\"')\n    return np.asarray([[float(r[1]), float(r[2])] for r in rows])\n\n\ndef moire_cell(pts):\n    c = int(np.argmin(np.linalg.norm(pts - pts.mean(axis=0), axis=1)))\n    rel = pts - pts[c]\n    d = np.linalg.norm(rel, axis=1)\n    order = np.argsort(d)[1:]\n    lam = d[order[0]]\n    near = [rel[i] for i in order if d[i] - lam <= TOL]\n    need(len(near) == 6, 'Not a triangular moire lattice around the centre site')\n    best = None\n    for i in range(6):\n        for j in range(i + 1, 6):\n            cross = abs(near[i][0] * near[j][1] - near[i][1] * near[j][0])\n            if cross > 0.1 * lam * lam and (best is None or cross < best[0] - 1e-9):\n                best = (cross, np.array([near[i], near[j]]))\n    area, basis = best\n    frac = np.linalg.solve(basis.T, rel.T).T\n    need(np.abs(frac - np.round(frac)).max() < 1e-5, 'Sites are not one Bravais lattice')\n    return float(lam), float(area)\n\n\ndef orientation(layer):\n    \"\"\"Six-fold phase average of the lattice vectors (second neighbours, length a) of one layer.\"\"\"\n    c = layer[np.argmin(np.linalg.norm(layer[:, :2] - layer[:, :2].mean(axis=0), axis=1))]\n    rel = layer[:, :2] - c[:2]\n    d = np.linalg.norm(rel, axis=1)\n    first = np.sort(d)[1]\n    second = d[d > first * 1.2].min()\n    vecs = rel[np.abs(d - second) < 1e-4]\n    need(len(vecs) == 6, 'Layer lattice vectors not found')\n    z = sum(cmath.exp(6j * math.atan2(v[1], v[0])) for v in vecs)\n    return math.degrees(cmath.phase(z)) / 6, float(second)\n\n\ndef electrons(q):\n    if 'completely fills one set of spin- and valley-degenerate' in q or 'complete filling of one set of spin- and valley-degenerate' in q:\n        return 4\n    need('half filling of one set of spin- and valley-degenerate' in q, 'Filling not stated')\n    return 2\n\n\ndef stated_conditions(q):\n    need('Model conditions:' in q and 'the only measured input is the twist angle' in q, 'Paper-parameter model conditions not stated')\n\n\ndef moire_quantity(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    stated_conditions(q)\n    inp = packet['inputs'][0]\n    if inp['format'] == 'xyz':\n        need('unstrained and rigidly twisted' in q, 'Rigid-twist assumption not stated')\n        atoms = np.asarray([[float(c) for c in p] for _, p in read_xyz(inp['text'])])\n        layers = sorted({round(float(z), 3) for z in atoms[:, 2]})\n        need(len(layers) == 2, 'Expected two layers')\n        (p0, a0), (p1, a1) = (orientation(atoms[np.abs(atoms[:, 2] - z) < 0.01]) for z in layers)\n        theta = abs((p1 - p0 + 30) % 60 - 30)\n        a = (a0 + a1) / 20                                # angstrom -> nm\n        value = a / (2 * math.sin(math.radians(theta) / 2))\n        return dict(judge_numeric(packet, key, value), parameters=dict(twist_deg=theta, a_nm=a),\n                    method='six-fold phase average per layer')\n    lam, area = moire_cell(aa_sites(inp))\n    if 'What is the moiré period' in q:\n        value = lam\n    elif 'area of one moiré unit cell' in q:\n        value = area\n    elif 'twist angle between the two layers' in q:\n        a = float(find(r'lattice constant is ([\\d.]+) nm', q, 'Lattice constant missing').group(1))\n        value = math.degrees(2 * math.asin(a / (2 * lam)))\n    else:\n        value = electrons(q) / area * 100\n    return dict(judge_numeric(packet, key, value), parameters=dict(period_nm=lam, cell_area_nm2=area),\n                method='primitive moire cell from AA sites')\n\n\ndef moire_design(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    stated_conditions(q)\n    cells = {inp['name']: moire_cell(aa_sites(inp)) for inp in packet['inputs']}\n    m = re.search(r'closest to ([\\d.]+) × 10¹² cm⁻²', q)\n    p = re.search(r'moiré period is closest to ([\\d.]+) nm', q)\n    need((m is None) != (p is None), 'Design goal not stated exactly once')\n    if m:\n        t, e = float(m.group(1)), electrons(q)\n        prop = {k: e / area * 100 for k, (lam, area) in cells.items()}\n    else:\n        t = float(p.group(1))\n        prop = {k: lam for k, (lam, area) in cells.items()}\n    ranked = sorted(prop, key=lambda k: abs(prop[k] - t))\n    need(abs(prop[ranked[1]] - t) > abs(prop[ranked[0]] - t) + 1e-6, 'Tie for closest candidate')\n    hits = [o['label'] for o in packet['options'] if o['value'].endswith('(%s)' % ranked[0])]\n    need(len(hits) == 1, 'Winner not named by exactly one option')\n    for o in packet['options']:\n        name = re.search(r'\\((\\S+)\\)$', o['value'])\n        need(name is not None and name.group(1) in cells, 'Option does not name a supplied file')\n    need(key['correct_label'] == hits[0], 'Key label disagrees with recomputed choice')\n    return dict(label=hits[0], parameters=prop, method='per-file primitive moire cell; goal rule')\n\n\nCHECKERS = {'moire_geometry': moire_quantity, 'moire_inference': moire_quantity, 'moire_design': moire_design}\n",
  "checkers/paper_design.py": "\"\"\"Independent checker for design_choice. No generation code is imported.\n\nThe checker reads the design card named in the answer key (hash-verified) and re-derives the task from what the\nstudent was given: the four candidate lines in candidates.txt, and the target thresholds printed in the question\ntext. Every threshold it enforces is parsed back out of the question, so a card whose stored threshold differs\nfrom the one the student was shown fails here. Comparisons are redone in Decimal, the \"all four candidates are\nmeasured\" rule is enforced again, and exactly one candidate must satisfy every constraint and be the one the\npaper chose. Whether the card renders the paper faithfully is not something code can verify (L1 compares each\nlocator with the original).\n\"\"\"\nimport json\nimport re\nfrom decimal import Decimal, localcontext\nfrom .common import need, verify_hashes\n\nOPS = {'>=': lambda a, b: a >= b, '>': lambda a, b: a > b, '<=': lambda a, b: a <= b, '<': lambda a, b: a < b}\nLOWER = ('>=', '>')\nMANTISSA = re.compile(r'^\\(?([<>]?)\\s*(-?\\d+(?:\\.\\d+)?)')\nEXPONENT = re.compile(r'× 10\\^(-?\\d+)')\nMARKER_BOUND = {'': None, '>': 'lower', '<': 'upper'}\n\n\ndef parse_display(display):\n    \"\"\"(bound implied by the printed inequality, value): '(1.07 ± 0.10) × 10^7', '> 16', '2.7 mmol g^-1'.\"\"\"\n    m = MANTISSA.match(display)\n    need(m is not None, 'Display string does not begin with a number: ' + display)\n    exponent = EXPONENT.search(display)\n    value = Decimal(m.group(2)) * (Decimal(10) ** int(exponent.group(1)) if exponent else 1)\n    return MARKER_BOUND[m.group(1)], value\n\n\ndef number(display):\n    bound, value = parse_display(display)\n    need(bound is None, 'A threshold carries its direction in the comparison, not in the printed number: ' + display)\n    return value\n\n\ndef card_of(packet, key):\n    paths = verify_hashes(key)\n    cards = [p for rel, p in paths.items() if rel.startswith('assets/families/design/') and rel.endswith('.json')]\n    need(len(cards) == 1, 'Exactly one design card must be recorded in the key')\n    card = json.loads(cards[0].read_text(encoding='utf-8'))\n    need(card.get('kind') == 'design_card' and card.get('family') == packet['family'], 'Card belongs to another family')\n    inputs = {i['name']: i['text'] for i in packet['inputs']}\n    need(set(inputs) == {'candidates.txt'}, 'A design packet attaches exactly candidates.txt')\n    lines = inputs['candidates.txt'].rstrip('\\n').split('\\n')\n    need(len(lines) == 4 and len(card['candidates']) == 4, 'Exactly four candidates required')\n    shown = sorted(card['candidates'], key=lambda c: c['id'])\n    for line, c in zip(lines, shown):\n        need(line == '%s: %s — %s' % (c['id'], c['name'], c['geometry']), 'Candidate %s differs from the card' % c['id'])\n    need(card['ask'] in packet['question'] and card['goal'] in packet['question'], 'Question does not state the goal')\n    return card, inputs\n\n\ndef targets(card, question):\n    \"\"\"Thresholds re-read from the question text; the card only says which property and direction each one tests.\"\"\"\n    out = []\n    for con in card['constraints']:\n        stated = '(%s) %s' % (con['key'], con['text'])\n        need(stated in question, 'Target %s is not stated in the question' % con['key'])\n        need(con['display'] in con['text'], 'Threshold %s is not printed in its own target text' % con['key'])\n        need(con['op'] in OPS, 'Unknown comparison ' + con['op'])\n        out.append((con['key'], con['property'], con['op'], number(con['display'])))\n    need(len({k for k, _, _, _ in out}) == len(out), 'Constraint keys must be distinct')\n    return out\n\n\ndef value_of(card, candidate, name):\n    if name in card.get('derived', {}):\n        parts = []\n        for k in card['derived'][name]['ratio']:\n            v, bound = value_of(card, candidate, k)\n            need(bound is None, 'A derived ratio needs exact measured values, not bounds')\n            parts.append(v)\n        return parts[0] / parts[1], None\n    entry = candidate['measured'].get(name)\n    need(entry is not None, 'Candidate %s has no measured %s' % (candidate['id'], name))\n    need(entry.get('locator'), 'Measured %s of %s has no place in the paper' % (name, candidate['id']))\n    bound, value = parse_display(entry['display'])\n    need(bound == entry.get('bound') and value == Decimal(repr(entry['value'])),\n         'Measured %s of %s is not stored as the paper prints it' % (name, candidate['id']))\n    return value, bound\n\n\ndef satisfied(op, value, threshold, bound):\n    ok = OPS[op](value, threshold)\n    if bound is None:\n        return ok\n    need(bound in ('lower', 'upper'), 'Unknown bound ' + str(bound))\n    need(ok if (bound == 'lower') == (op in LOWER) else not ok,\n         'A %s bound cannot settle the constraint %s %s' % (bound, op, threshold))\n    return ok\n\n\ndef design_choice(packet, key):\n    card, _ = card_of(packet, key)\n    constraints = targets(card, packet['question'])\n    by_text = {'%s: %s' % (c['id'], c['name']): c for c in card['candidates']}\n    need(len(by_text) == 4 and {o['value'] for o in packet['options']} == set(by_text),\n         'Options are not the four card candidates')\n    margin = Decimal(repr(card['margin']))\n    alive, failures = [], {}\n    with localcontext() as ctx:\n        ctx.prec = 50\n        for o in packet['options']:\n            c = by_text[o['value']]\n            bad = []\n            for name, prop, op, threshold in constraints:\n                value, bound = value_of(card, c, prop)\n                need(threshold != 0, 'A threshold of zero cannot carry a margin')\n                ratio = value / threshold\n                need(ratio >= margin or ratio <= 1 / margin, 'Candidate %s sits within the margin of %s' % (c['id'], name))\n                if not satisfied(op, value, threshold, bound):\n                    bad.append(name)\n            failures[c['id']] = bad\n            if not bad:\n                alive.append((o['label'], c))\n    need(len(alive) == 1, '%d candidates meet the target (need exactly 1)' % len(alive))\n    label, best = alive[0]\n    need(best['id'] == card['paper_choice'], 'The candidate that meets the target is not the one the paper chose')\n    need(key['correct_label'] == label, 'Key label disagrees with the measured values')\n    return dict(label=label, parameters=dict(card=card['id'], choice=best['id'], failures=failures),\n                method='Decimal re-evaluation of the thresholds parsed from the question against the hashed card')\n\n\nCHECKERS = {'design_choice': design_choice}\n",
  "checkers/quantum_dot.py": "\"\"\"Independent checker for the CdSe quantum-dot families (quantum, 1-10 nm).\nNo generation code is imported. The sizing polynomial and extinction law are read from the question text;\nthe diameter is the largest atom-atom distance (own chunked search + Decimal on the winning pair); the peak\nis the real root of the quartic in the stated range (numpy.roots, not bisection).\n\"\"\"\nimport math\nimport re\nimport numpy as np\nfrom .common import need, find, read_xyz, verify_hashes, judge_numeric\nfrom .migrated import dec_dist\n\n\ndef same_as_asset(packet, key):\n    by_name = {p.name: p for p in verify_hashes(key).values()}\n    for inp in packet['inputs']:\n        need(inp['name'] in by_name and by_name[inp['name']].read_bytes() == inp['text'].encode('utf-8'), 'Input differs: ' + inp['name'])\n\n\ndef curve(q):\n    m = find(r'D = ([\\d.e-]+)·λ⁴ − ([\\d.e-]+)·λ³ \\+ ([\\d.e-]+)·λ² − ([\\d.]+)·λ \\+ ([\\d.]+)', q, 'Sizing polynomial not stated')\n    c = [float(m.group(1)), -float(m.group(2)), float(m.group(3)), -float(m.group(4)), float(m.group(5))]\n    lo, hi = (float(x) for x in find(r'valid for (\\d+)–(\\d+) nm', q, 'Validity range not stated').groups())\n    e = find(r'ε = (\\d+)·D\\^([\\d.]+)', q, 'Extinction law not stated')\n    need('largest distance between any two atoms' in q, 'Size definition not stated')\n    need('Model conditions:' in q and 'ideal spherical cut' in q, 'Model particle conditions not stated')\n    return c, lo, hi, float(e.group(1)), float(e.group(2))\n\n\ndef diameter(text):\n    a = np.asarray([[float(v) for v in p] for _, p in read_xyz(text)])\n    best, pair = -1.0, None\n    for i in range(0, len(a), 400):\n        d2 = ((a[i:i + 400, None, :] - a[None, :, :]) ** 2).sum(axis=2)\n        k = int(d2.argmax())\n        if d2.flat[k] > best:\n            best, pair = float(d2.flat[k]), (i + k // len(a), k % len(a))\n    return float(dec_dist(a[pair[0]].tolist(), a[pair[1]].tolist())) / 10\n\n\ndef peak(c, lo, hi, d):\n    roots = [float(r.real) for r in np.roots([c[0], c[1], c[2], c[3], c[4] - d]) if abs(r.imag) < 1e-9 and lo <= r.real <= hi]\n    need(len(roots) == 1, 'Sizing curve has %d roots in range' % len(roots))\n    return roots[0]\n\n\ndef qdot_quantity(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    c, lo, hi, e0, ex = curve(q)\n    d = diameter(packet['inputs'][0]['text'])\n    if 'first excitonic absorption peak?' in q:\n        value = peak(c, lo, hi, d)\n    elif 'molar extinction coefficient' in q:\n        value = e0 * d ** ex / 1e5\n    else:\n        a = float(find(r'absorbance of ([\\d.]+) at the first excitonic peak', q, 'Absorbance missing').group(1))\n        l = float(find(r'in a ([\\d.]+) cm cuvette', q, 'Path length missing').group(1))\n        need('µM' in q, 'Unit missing')\n        value = a / (e0 * d ** ex * l) * 1e6\n    return dict(judge_numeric(packet, key, value), parameters=dict(D_nm=d), method='Decimal Dmax; quartic roots')\n\n\ndef qdot_design(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    c, lo, hi, e0, ex = curve(q)\n    d = {inp['name']: diameter(inp['text']) for inp in packet['inputs']}\n    lam = {k: peak(c, lo, hi, v) for k, v in d.items()}\n    close = re.search(r'peak is closest to ([\\d.]+) nm', q)\n    beyond = re.search(r'smallest particle whose first excitonic absorption peak lies at or beyond ([\\d.]+) nm', q)\n    need((close is None) != (beyond is None), 'Design goal not stated exactly once')\n    if close:\n        t = float(close.group(1))\n        ranked = sorted(lam, key=lambda k: abs(lam[k] - t))\n        need(abs(lam[ranked[1]] - t) > abs(lam[ranked[0]] - t) + 1e-6, 'Tie')\n        winner = ranked[0]\n    else:\n        t = float(beyond.group(1))\n        ok = [k for k in lam if lam[k] >= t]\n        need(ok, 'No candidate meets the target')\n        winner = min(ok, key=lambda k: d[k])\n    hits = [o['label'] for o in packet['options'] if o['value'] == winner]\n    need(len(hits) == 1 and all(o['value'] in lam for o in packet['options']), 'Options must be the supplied file names')\n    need(key['correct_label'] == hits[0], 'Key label disagrees with recomputed choice')\n    return dict(label=hits[0], parameters=dict(D_nm=d, peak_nm=lam), method='per-file Dmax; quartic roots; goal rule')\n\n\nCHECKERS = {'qdot_optics': qdot_quantity, 'qdot_design': qdot_design}\n",
  "checkers/rotational.py": "\"\"\"Independent checkers for rotational_line and isotopologue_design. No generation code is imported.\n\nMasses, h and the atomic mass unit are read from the question text; the attached XYZ must equal the hashed source asset.\nThe inertia tensor is accumulated in Decimal about the centre of mass, and the principal moments are the roots of its\ncharacteristic cubic in closed (trigonometric) form; the generator diagonalises with Jacobi rotations instead.\n\"\"\"\nimport math\nimport re\nfrom decimal import Decimal, localcontext\nfrom .common import need, find, read_xyz, verify_hashes, judge_numeric, dist\n\n# Covalent radii (Cordero et al., Dalton Trans. 2008) for the checker's own attachment rule.\nRADII = {'H': 0.31, 'C': 0.76, 'N': 0.71, 'O': 0.66, 'S': 1.05, 'Si': 1.11, 'Cl': 1.02, 'Br': 1.20, 'I': 1.39, 'F': 0.57, 'P': 1.07}\n\n# Rigid asymmetric rotor, J = 1 levels above 0_00 (Ka, Kc labels): the sum of the two constants about the axes\n# perpendicular to the one the state rotates about.\nJ1_LEVELS = {'1_01': ('B', 'C'), '1_11': ('A', 'C'), '1_10': ('A', 'B')}\nRATIO, MIN_MHZ = 1.15, 0.5       # design: the keyed substitution must lead clearly\nSUPERSCRIPT = str.maketrans('⁰¹²³⁴⁵⁶⁷⁸⁹', '0123456789')\n\n\ndef model(question):\n    block = find(r'masses of the most abundant isotopes: (.+?); rotational constants', question, 'Isotope masses not stated').group(1)\n    masses = {e: Decimal(v) for e, v in re.findall(r'\\b([A-Z][a-z]?) (\\d+\\.\\d+) u', block)}\n    need(masses, 'No masses parsed')\n    h = find(r'h = ([\\d.]+)×10⁻([⁰¹²³⁴⁵⁶⁷⁸⁹]+) J s', question, 'Planck constant not stated')\n    u = find(r'1 u = ([\\d.]+)×10⁻([⁰¹²³⁴⁵⁶⁷⁸⁹]+) kg', question, 'Atomic mass unit not stated')\n    need('rigid rotor' in question and 'about the centre of mass' in question and 'h/(8π²I)' in question, 'Rotor model not stated')\n    with localcontext() as ctx:\n        ctx.prec = 40\n        planck = Decimal(h.group(1)).scaleb(-int(h.group(2).translate(SUPERSCRIPT)))\n        dalton = Decimal(u.group(1)).scaleb(-int(u.group(2).translate(SUPERSCRIPT)))\n        factor = planck / (8 * Decimal(math.pi) ** 2 * dalton * Decimal('1e-20')) / Decimal(10) ** 6   # MHz u A^2\n    return masses, float(factor)\n\n\ndef molecule(packet, key):\n    [item] = [i for i in packet['inputs'] if i['format'] == 'xyz']\n    paths = verify_hashes(key)\n    need(len(paths) == 1, 'Exactly one source asset expected')\n    [path] = paths.values()\n    source = path.read_bytes().decode('utf-8-sig').split('\\n')\n    attached = item['text'].split('\\n')\n    # Count line and every atom row verbatim; only the comment line may differ (dataset ids are removed from it).\n    need(len(attached) == len(source) and attached[0] == source[0] and attached[2:] == source[2:],\n         'Attached XYZ differs from the source asset')\n    need('Geom-' not in attached[1], 'Dataset conformer id in the attached comment line')\n    return read_xyz(item['text'])\n\n\ndef principal_moments(atoms, masses):\n    need({e for e, _ in atoms} <= set(masses), 'A mass is missing for an element present')\n    with localcontext() as ctx:\n        ctx.prec = 40\n        w = [masses[e] for e, _ in atoms]\n        total = sum(w)\n        com = [sum(m * p[k] for m, (_, p) in zip(w, atoms)) / total for k in range(3)]\n        t = [[Decimal(0)] * 3 for _ in range(3)]\n        for m, (_, p) in zip(w, atoms):\n            r = [p[k] - com[k] for k in range(3)]\n            rr = sum(x * x for x in r)\n            for i in range(3):\n                for j in range(3):\n                    t[i][j] += m * ((rr if i == j else 0) - r[i] * r[j])\n    return eigen_symmetric([[float(x) for x in row] for row in t])\n\n\ndef eigen_symmetric(a):\n    \"\"\"Closed-form eigenvalues of a symmetric 3x3 matrix (trigonometric solution of the characteristic cubic).\"\"\"\n    p1 = a[0][1] ** 2 + a[0][2] ** 2 + a[1][2] ** 2\n    q = (a[0][0] + a[1][1] + a[2][2]) / 3\n    p2 = (a[0][0] - q) ** 2 + (a[1][1] - q) ** 2 + (a[2][2] - q) ** 2 + 2 * p1\n    if p2 == 0:\n        return [q, q, q]\n    p = math.sqrt(p2 / 6)\n    b = [[(a[i][j] - (q if i == j else 0)) / p for j in range(3)] for i in range(3)]\n    det = (b[0][0] * (b[1][1] * b[2][2] - b[1][2] * b[2][1]) - b[0][1] * (b[1][0] * b[2][2] - b[1][2] * b[2][0])\n           + b[0][2] * (b[1][0] * b[2][1] - b[1][1] * b[2][0]))\n    phi = math.acos(max(-1.0, min(1.0, det / 2))) / 3\n    big = q + 2 * p * math.cos(phi)\n    small = q + 2 * p * math.cos(phi + 2 * math.pi / 3)\n    return sorted([small, 3 * q - big - small, big])\n\n\ndef rotational_constants(atoms, masses, factor):\n    ia, ib, ic = principal_moments(atoms, masses)\n    need(ia > 1e-6, 'Degenerate rotor')\n    return dict(A=factor / ia, B=factor / ib, C=factor / ic)\n\n\ndef level(question):\n    m = find(r'J_KaKc = (1_\\d\\d) ← 0_00', question, 'Transition not stated')\n    need(m.group(1) in J1_LEVELS, 'Unsupported transition ' + m.group(1))\n    return m.group(1)\n\n\ndef frequency(abc, label):\n    x, y = J1_LEVELS[label]\n    return abc[x] + abc[y]\n\n\ndef rotational_line(packet, key):\n    q = packet['question']\n    masses, factor = model(q)\n    atoms = molecule(packet, key)\n    label = level(q)\n    abc = rotational_constants(atoms, masses, factor)\n    return dict(judge_numeric(packet, key, frequency(abc, label)),\n                parameters=dict(transition=label, constants_MHz={k: round(v, 4) for k, v in abc.items()}),\n                method='Decimal centre of mass and inertia tensor; closed-form cubic eigenvalues; J=1 level table')\n\n\ndef isotopologue_design(packet, key):\n    q = packet['question']\n    masses, factor = model(q)\n    deuterium = Decimal(find(r'deuterium, D (\\d+\\.\\d+) u', q, 'Deuterium mass not stated').group(1))\n    need('largest absolute shift' in q, 'Design objective not stated')\n    atoms = molecule(packet, key)\n    label = level(q)\n    listed = [int(x) for x in re.findall(r'H(\\d+)', find(r'hydrogen atoms ((?:H\\d+(?:, )?)+) \\(rows', q, 'Candidates not listed').group(1))]\n    rows = {}\n    for o in packet['options']:\n        m = re.fullmatch(r'H(\\d+) \\(row (\\d+)\\)', o['value'])\n        need(m is not None and m.group(1) == m.group(2), 'Option must name a hydrogen by its row')\n        rows[o['label']] = int(m.group(2))\n    need(sorted(rows.values()) == sorted(listed), 'Options differ from the listed candidates')\n    need(all(1 <= r <= len(atoms) and atoms[r - 1][0] == 'H' for r in rows.values()), 'A candidate is not a hydrogen atom')\n    # Each stated attachment 'Hn is bonded to Xm' must hold under the checker's own covalent-radius rule (nearest atom).\n    claims = dict((int(h), (e, int(x))) for h, e, x in re.findall(r'H(\\d+) is bonded to ([A-Z][a-z]?)(\\d+),', q))\n    need(sorted(claims) == sorted(listed), 'Every candidate needs a stated attachment')\n    for h, (element, x) in claims.items():\n        need(1 <= x <= len(atoms) and atoms[x - 1][0] == element, 'Stated parent atom %s%d does not match the XYZ' % (element, x))\n        d = {k: float(dist(atoms[h - 1][1], p)) for k, (_, p) in enumerate(atoms, 1) if k != h}\n        need(min(d, key=d.get) == x and d[x] <= 1.25 * (RADII['H'] + RADII[element]), 'H%d is not bonded to %s%d' % (h, element, x))\n    parent = frequency(rotational_constants(atoms, masses, factor), label)\n    shift = {}\n    for l, r in rows.items():\n        heavy = dict(masses, Dsub=deuterium)\n        swapped = [('Dsub', p) if i == r - 1 else (e, p) for i, (e, p) in enumerate(atoms)]\n        shift[l] = frequency(rotational_constants(swapped, heavy, factor), label) - parent\n    ranked = sorted(shift, key=lambda l: -abs(shift[l]))\n    first, second = abs(shift[ranked[0]]), abs(shift[ranked[1]])\n    need(first >= RATIO * second and first - second >= MIN_MHZ, 'No clear largest shift')\n    need(key['correct_label'] == ranked[0], 'Key label %s != recomputed %s' % (key['correct_label'], ranked[0]))\n    return dict(label=ranked[0], parameters=dict(transition=label, parent_MHz=round(parent, 4),\n                                                 shifts_MHz={l: round(v, 4) for l, v in shift.items()}),\n                method='Decimal inertia tensor with the substituted mass; closed-form cubic eigenvalues')\n\n\nCHECKERS = {'rotational_line': rotational_line, 'isotopologue_design': isotopologue_design}\n",
  "checkers/stereo.py": "\"\"\"Independent checkers for the stereochemistry ladder (no generation code imported).\n\nOwn implementations of: bonding (Cordero radii x 1.25), first-shell classes, stereo\nelements (4-coordinate centres; pyramidal S/P; aziridine N; cis/trans at trigonal C=C /\nC=N), a colour-refinement graph invariant, and rotation-invariant matching of supplied\nstructures to the hash-verified dataset extract (distance matrix + handedness), so that\nproperties are never looked up by label or id.\n\"\"\"\nimport hashlib\nimport json\nimport math\nfrom .common import need, find, read_xyz, verify_hashes, LABELS, vec, dot, cross\n\nRADII = {'H': 0.31, 'C': 0.76, 'N': 0.71, 'O': 0.66, 'S': 1.05, 'Cl': 1.02, 'P': 1.07, 'F': 0.57,\n         'Si': 1.11, 'Br': 1.20, 'I': 1.39}     # covalent radii, Cordero et al., Dalton Trans. 2008\n\n\ndef floats(atoms):\n    return [e for e, _ in atoms], [tuple(float(c) for c in p) for _, p in atoms]\n\n\ndef bonds(el, pts):\n    return {(i, j) for i in range(len(pts)) for j in range(i + 1, len(pts))\n            if math.dist(pts[i], pts[j]) <= 1.25 * (RADII[el[i]] + RADII[el[j]])}\n\n\ndef adjacency(n, edges):\n    adj = [set() for _ in range(n)]\n    for i, j in edges:\n        adj[i].add(j)\n        adj[j].add(i)\n    return adj\n\n\ndef stereo_elements(el, pts, edges):\n    adj = adjacency(len(el), edges)\n    cls = [(el[i], tuple(sorted(el[j] for j in adj[i]))) for i in range(len(el))]\n    centres, sides = {}, {}\n    for i in range(len(el)):\n        nb = sorted(adj[i])\n        if len({cls[j] for j in nb}) != len(nb):\n            continue\n        ring3 = any(k in adj[j] for j in nb for k in nb if j != k)\n        if len(nb) == 4 or (len(nb) == 3 and (el[i] in ('S', 'P') or (el[i] == 'N' and ring3))):\n            u, v, w = (vec(pts[i], pts[j]) for j in nb[:3])\n            t = dot(cross(u, v), w)\n            if len(nb) == 3 and abs(t) < 0.1 * math.sqrt(dot(u, u) * dot(v, v) * dot(w, w)):\n                continue\n            centres[i] = t > 0\n    trig = {i for i in range(len(el)) if (el[i] == 'C' and len(adj[i]) == 3) or (el[i] == 'N' and len(adj[i]) == 2)}\n    for i, j in edges:\n        if i in trig and j in trig:\n            si, sj = sorted(adj[i] - {j}), sorted(adj[j] - {i})\n            if (len(si) == 2 and cls[si[0]] == cls[si[1]]) or (len(sj) == 2 and cls[sj[0]] == cls[sj[1]]):\n                continue\n            # cis if the two reference substituents lie on the same side of the plane through\n            # the double bond perpendicular to the substituent plane (sign of projections).\n            axis = vec(pts[i], pts[j])\n            a, b = vec(pts[i], pts[si[0]]), vec(pts[j], pts[sj[0]])\n            pa = [x - dot(a, axis) / dot(axis, axis) * y for x, y in zip(a, axis)]\n            pb = [x - dot(b, axis) / dot(axis, axis) * y for x, y in zip(b, axis)]\n            sides[(i, j)] = dot(pa, pb) > 0\n    return centres, sides\n\n\ndef invariant(el, edges, rounds=4):\n    adj = adjacency(len(el), edges)\n    colour = list(el)\n    for _ in range(rounds):     # colour refinement; md5 keeps labels comparable across molecules\n        colour = [hashlib.md5(repr((colour[i], sorted(colour[j] for j in adj[i]))).encode()).hexdigest()\n                  for i in range(len(el))]\n    return sorted(colour), sorted(len(a) for a in adj)\n\n\ndef relation(a, b, shared_order):\n    (ea, pa), (eb, pb) = floats(a), floats(b)\n    need(sorted(ea) == sorted(eb), 'Structures have different formulas')\n    ga, gb = bonds(ea, pa), bonds(eb, pb)\n    if not shared_order or ea != eb or ga != gb:\n        need(invariant(ea, ga) != invariant(eb, gb), 'Cannot decide constitution without atom correspondence')\n        return 'constitutional', {}\n    (ca, sa), (cb, sb) = stereo_elements(ea, pa, ga), stereo_elements(eb, pb, gb)\n    need(set(ca) == set(cb) and set(sa) == set(sb), 'Stereo elements differ: undecidable')\n    inverted = [k for k in ca if ca[k] != cb[k]]\n    switched = [k for k in sa if sa[k] != sb[k]]\n    facts = dict(centres=sorted(ca), inverted=sorted(inverted), switched=[list(k) for k in sorted(switched)])\n    if not inverted and not switched:\n        return 'same', facts\n    if ca and len(inverted) == len(ca) and not switched:\n        return 'enantiomer', facts\n    return 'diastereomer', facts\n\n\ndef dmatrix_gap(p, q):\n    n = len(p)\n    diffs = [math.dist(p[i], p[j]) - math.dist(q[i], q[j]) for i in range(n) for j in range(i + 1, n)]\n    return math.sqrt(math.fsum(d * d for d in diffs) / len(diffs))\n\n\ndef find_in(atoms, data_list):\n    \"\"\"Try every hash-verified extract; returns (dataset, conformer, mirrored).\"\"\"\n    for d in data_list:\n        if floats(atoms)[0] == d['elements']:\n            try:\n                return (d,) + locate(atoms, d)\n            except Exception:\n                continue\n    need(False, 'Structure not found in any dataset extract')\n\n\ndef locate(atoms, data):\n    \"\"\"Dataset conformer with the same internal geometry and handedness; or the exact mirror\n    image of one (returned with mirrored=True: scalar properties equal by reflection symmetry).\"\"\"\n    el, pts = floats(atoms)\n    need(el == data['elements'], 'Atom order differs from the dataset extract')\n    hits = []\n    for c in data['conformers']:\n        if dmatrix_gap(pts, c['xyz']) < 1e-5:\n            same = stereo_elements(el, pts, bonds(el, pts))[0] == stereo_elements(el, c['xyz'], bonds(el, c['xyz']))[0]\n            hits.append((c, not same))\n    need(len(hits) >= 1, 'Structure not found in the dataset extract')\n    exact = [h for h in hits if not h[1]]\n    return exact[0] if exact else hits[0]\n\n\ndef files(packet):\n    return {i['name']: read_xyz(i['text']) for i in packet['inputs']}\n\n\ndef datasets(key):\n    return [json.loads(p.read_text(encoding='utf-8')) for p in verify_hashes(key).values()]\n\n\n# ------------------------------------------------------------------ perception\nOPTION_TEXT = {'same': 'the same compound', 'enantiomer': 'an enantiomer', 'diastereomer': 'a diastereomer',\n               'constitutional': 'a constitutional isomer'}\n\n\ndef stereo_relationship(packet, key):\n    q = packet['question']\n    need('rigidly rotated' in q and 'atom order may differ' in q, 'Question must disclose the rotation and atom order')\n    f = files(packet)\n    need(set(f) == {'S0.xyz', 'X.xyz'}, 'Need S0.xyz and X.xyz')\n    data = datasets(key)\n    same_molecule = len(data) == 1\n    rel, facts = relation(f['S0.xyz'], f['X.xyz'], same_molecule)\n    if same_molecule:          # dataset labels must agree with the geometric verdict\n        (c0, m0), (c1, m1) = locate(f['S0.xyz'], data[0]), locate(f['X.xyz'], data[0])\n        need(not m0 and not m1, 'Supplied structures are not dataset structures')\n        need((c0['isomer'] == c1['isomer']) == (rel == 'same'), 'Geometry disagrees with dataset stereoisomer labels')\n    labels = [o['label'] for o in packet['options'] if o['value'].startswith(OPTION_TEXT[rel])]\n    need(len(labels) == 1, 'Exactly one option must name the relationship')\n    need(key['correct_label'] == labels[0], 'Key label %s != recomputed %s' % (key['correct_label'], labels[0]))\n    return dict(label=labels[0], recomputed=rel, parameters=dict(same_dataset_molecule=same_molecule), facts=facts,\n                method='own bond graph, stereo elements and colour-refinement invariant')\n\n\n# ------------------------------------------------------------------ inference\ndef stereo_property_inference(packet, key):\n    q = packet['question']\n    margin_e = float(find(r'at least ([\\d.]+) eV', q, 'Energy margin not stated').group(1))\n    margin_mu = float(find(r'and ([\\d.]+) e·Å in dipole', q, 'Dipole margin not stated').group(1))\n    f = files(packet)\n    [data] = datasets(key)\n    rel, facts = relation(f['S0.xyz'], f['X.xyz'], True)\n    need(rel == 'diastereomer', 'S0 and X must be diastereomers, found ' + rel)\n    (c0, m0), (c1, m1) = locate(f['S0.xyz'], data), locate(f['X.xyz'], data)\n    need(not m0 and not m1, 'Supplied structures are not dataset structures')\n    de, dmu = c1['e_pbe0_mbd_eV'] - c0['e_pbe0_mbd_eV'], c1['dipole_eA'] - c0['dipole_eA']\n    need(abs(de) >= margin_e and abs(dmu) >= margin_mu, 'Differences below the stated margins')\n    verdicts = []\n    for o in packet['options']:\n        energy = find(r'X is (lower|higher) in energy', o['value'], 'Option lacks energy direction').group(1)\n        dipole = find(r'has a (larger|smaller) dipole', o['value'], 'Option lacks dipole direction').group(1)\n        verdicts.append((energy == 'higher') == (de > 0) and (dipole == 'larger') == (dmu > 0))\n    need(sum(verdicts) == 1 and len({o['value'] for o in packet['options']}) == 4, 'Exactly one statement must hold')\n    label = LABELS[verdicts.index(True)]\n    need(key['correct_label'] == label, 'Key label %s != recomputed %s' % (key['correct_label'], label))\n    return dict(label=label, recomputed=dict(delta_energy_eV=round(de, 6), delta_dipole_eA=round(dmu, 6)), facts=facts,\n                method='structures matched to dataset by distance matrix and handedness; signs and margins recomputed')\n\n\n# ------------------------------------------------------------------ design\ndef stereo_design_selection(packet, key):\n    q = packet['question']\n    margin = float(find(r'at least ([\\d.]+) eV \\(1 kcal/mol\\) lower', q, 'Goal margin not stated').group(1))\n    need('same atoms, same bonds' in q and 'conformation alone does not count' in q, 'Allowed modification not stated')\n    f = files(packet)\n    need(set(f) == {'S0.xyz'} | {'candidate_%s.xyz' % l for l in LABELS}, 'Need S0 and four candidates')\n    data = datasets(key)\n    main, s0, mirrored = find_in(f['S0.xyz'], data)\n    need(not mirrored, 'S0 is not a dataset structure')\n    verdicts, rows = [], {}\n    for label in LABELS:\n        cand = f['candidate_%s.xyz' % label]\n        home, c, mir = find_in(cand, data)\n        rel, _ = relation(f['S0.xyz'], cand, home is main)\n        energy = c['e_pbe0_mbd_eV']                  # mirror image: equal by reflection symmetry\n        ok = rel in ('enantiomer', 'diastereomer') and energy - s0['e_pbe0_mbd_eV'] <= -margin\n        verdicts.append(ok)\n        rows[label] = dict(relation=rel, delta_energy_eV=round(energy - s0['e_pbe0_mbd_eV'], 6), mirror_of_dataset=mir)\n    need(sum(verdicts) == 1, '%d candidates satisfy constraint and goal (need exactly 1)' % sum(verdicts))\n    label = LABELS[verdicts.index(True)]\n    need(key['correct_label'] == label, 'Key label %s != recomputed %s' % (key['correct_label'], label))\n    return dict(label=label, recomputed=label, options=rows,\n                method='own relationship classification per candidate; energies by dataset matching or reflection symmetry')\n",
  "checkers/superlattice.py": "\"\"\"Independent checkers for the nanoparticle-superlattice families (materials, 10-100 nm).\nNo generation code is imported. The lattice is recovered from the coordinates alone: a primitive\nbasis is chosen among the nearest-neighbour vectors (smallest cell volume), every particle must sit\non an integer combination of it, and Bragg positions come from the reciprocal lattice, not from\nd-spacing formulas.\n\"\"\"\nimport itertools\nimport math\nimport re\nimport numpy as np\nfrom .common import need, find, read_xyz, verify_hashes, judge_numeric, rounded\n\nTOL = 1e-4     # nm\n\n\ndef points(inp):\n    return np.asarray([[float(c) for c in p] for _, p in read_xyz(inp['text'])])\n\n\ndef same_as_asset(packet, key):\n    paths = verify_hashes(key)\n    by_name = {p.name: p for p in paths.values()}\n    for inp in packet['inputs']:\n        need(inp['name'] in by_name and by_name[inp['name']].read_bytes() == inp['text'].encode('utf-8'),\n             'Input differs from the published model crystallite: ' + inp['name'])\n\n\ndef analyse(pts):\n    c = int(np.argmin(np.linalg.norm(pts - pts.mean(axis=0), axis=1)))\n    rel = pts - pts[c]\n    d = np.linalg.norm(rel, axis=1)\n    order = np.argsort(d)[1:]\n    nn = d[order[0]]\n    first = [i for i in order if d[i] - nn <= TOL]\n    vecs = rel[first]\n    best = None\n    for i, j, k in itertools.combinations(range(len(vecs)), 3):\n        vol = abs(np.linalg.det(vecs[[i, j, k]]))\n        if vol > 0.05 * nn ** 3 and (best is None or vol < best[0] - 1e-6 * nn ** 3):   # skip (numerically) coplanar triples\n            best = (vol, vecs[[i, j, k]])\n    need(best is not None, 'No primitive basis among nearest-neighbour vectors')\n    vol, basis = best\n    frac = np.linalg.solve(basis.T, rel.T).T\n    need(np.abs(frac - np.round(frac)).max() < 1e-5, 'Particles do not lie on one Bravais lattice')\n    recip = 2 * math.pi * np.linalg.inv(basis).T\n    norms = sorted(float(np.linalg.norm(np.array(h) @ recip)) for h in itertools.product(range(-4, 5), repeat=3) if any(h))\n    g = []                                   # distinct |G| values; symmetry-equivalent vectors agree to ~1e-8 relative\n    for x in norms:\n        if not g or x - g[-1] > 1e-6 * x:\n            g.append(x)\n    # Shells for the centre particle (count, mean distance)\n    shells = []\n    for i in order:\n        if shells and d[i] - shells[-1][1] <= TOL:\n            shells[-1][0].append(d[i])\n        else:\n            shells.append(([d[i]], d[i]))\n    shells = [(len(s), sum(s) / len(s)) for s, _ in shells]\n    fcc = shells[0][0] == 12 and shells[1][0] == 6 and abs(shells[1][1] / shells[0][1] - math.sqrt(2)) < 1e-5\n    return dict(nn=float(nn), volume=float(vol), g=g, shells=shells, fcc=fcc)\n\n\ndef stated_conditions(q):\n    need('Model conditions:' in q and 'the only measured input is' in q, 'Paper-parameter model conditions not stated')\n\n\ndef superlattice_shell(packet, key):\n    same_as_asset(packet, key)\n    stated_conditions(packet['question'])\n    need('nearest the centroid' in packet['question'], 'Centre particle not defined')\n    lat = analyse(points(packet['inputs'][0]))\n    n, dist = lat['shells'][0]\n    want = '%d at %s nm' % (n, rounded(dist, 2))\n    hits = [o['label'] for o in packet['options'] if o['value'] == want]\n    need(len(hits) == 1, 'Recomputed shell %s matches %d options' % (want, len(hits)))\n    need(key['correct_label'] == hits[0], 'Key label disagrees with recomputed shell')\n    for o in packet['options']:\n        m = re.fullmatch(r'(\\d+) at ([\\d.]+) nm', o['value'])\n        need(m is not None, 'Option not in \"N at D nm\" form')\n    return dict(label=hits[0], parameters=dict(count=n, distance_nm=dist), method='shells around the centroid particle')\n\n\ndef superlattice_quantity(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    stated_conditions(q)\n    lat = analyse(points(packet['inputs'][0]))\n    if 'conventional cubic unit cell' in q:\n        need(lat['fcc'], 'Lattice is not face-centred cubic; conventional cell undefined here')\n        value = (4 * lat['volume']) ** (1 / 3)\n    elif 'close-packed' in q:\n        value = 2 * math.pi / lat['g'][0]                  # densest planes = shortest reciprocal vector\n    elif 'first (lowest-q) Bragg reflection' in q:\n        need('q = 4π sinθ/λ' in q and 'identical point scatterers' in q, 'q convention or scatterer model missing')\n        value = lat['g'][0]\n    elif 'second distinct Bragg reflection' in q:\n        need('q = 4π sinθ/λ' in q and 'identical point scatterers' in q, 'q convention or scatterer model missing')\n        value = lat['g'][1]\n    else:\n        core = float(find(r'core diameter of ([\\d.]+) nm', q, 'Core diameter missing').group(1))\n        need('percentage of the total volume is gold' in q, 'Unknown quantity')\n        value = (4 / 3) * math.pi * (core / 2) ** 3 / lat['volume'] * 100      # one particle per primitive cell\n    return dict(judge_numeric(packet, key, value), parameters=dict(nn_nm=lat['nn'], primitive_volume_nm3=lat['volume']),\n                method='primitive basis from coordinates; reciprocal lattice')\n\n\ndef superlattice_design(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    stated_conditions(q)\n    props = {}\n    for inp in packet['inputs']:\n        lat = analyse(points(inp))\n        props[inp['name']] = dict(nn=lat['nn'], q=lat['g'][0], volume=lat['volume'])\n    m = re.search(r'closest to q = ([\\d.]+) nm⁻¹', q)\n    n = re.search(r'nearest-neighbour spacing of the particles is closest to ([\\d.]+) nm', q)\n    f = re.search(r'at least ([\\d.]+) % of the volume is gold \\(solid gold cores of diameter ([\\d.]+) nm', q)\n    need(sum(x is not None for x in (m, n, f)) == 1, 'Design goal not stated exactly once')\n    if m or n:\n        prop, t = ('q', float(m.group(1))) if m else ('nn', float(n.group(1)))\n        ranked = sorted(props, key=lambda k: abs(props[k][prop] - t))\n        need(abs(props[ranked[1]][prop] - t) > abs(props[ranked[0]][prop] - t) + 1e-6, 'Tie for closest candidate')\n        winner = ranked[0]\n    else:\n        t, core = float(f.group(1)), float(f.group(2))\n        gold = {k: (4 / 3) * math.pi * (core / 2) ** 3 / v['volume'] * 100 for k, v in props.items()}\n        ok = [k for k in props if gold[k] >= t]\n        need(ok, 'No candidate satisfies the constraint')\n        winner = max(ok, key=lambda k: props[k]['nn'])\n    hits = [o['label'] for o in packet['options'] if o['value'].endswith('(%s)' % winner)]\n    need(len(hits) == 1, 'Winning file named by %d options' % len(hits))\n    need(len({o['value'] for o in packet['options']}) == 4, 'Duplicate options')\n    for o in packet['options']:\n        name = re.search(r'\\((\\S+\\.xyz)\\)$', o['value'])\n        need(name is not None and name.group(1) in props, 'Option does not name a supplied file')\n    need(key['correct_label'] == hits[0], 'Key label disagrees with recomputed choice')\n    return dict(label=hits[0], parameters={k: dict(v) for k, v in props.items()}, method='per-file lattice analysis; goal rule')\n\n\nCHECKERS = {'superlattice_shell': superlattice_shell, 'superlattice_metric': superlattice_quantity,\n            'superlattice_saxs': superlattice_quantity, 'superlattice_design': superlattice_design}\n\n\n# ------------------------------------------------------------------ opal photonic crystals\ndef spheres(inp):\n    lines = inp['text'].splitlines()\n    rows = [l.split() for l in lines[2:] if l.strip()]\n    need(lines and lines[0].strip().isdigit() and int(lines[0]) == len(rows), 'Sphere file count invalid')\n    need(all(len(r) == 4 and r[0] == 'sphere' for r in rows), 'Rows must be \"sphere x y z\"')\n    return np.asarray([[float(v) for v in r[1:]] for r in rows])\n\n\ndef optics(q, lat):\n    \"\"\"Effective index from the question; sphere volume fraction from the primitive cell (touching spheres).\"\"\"\n    need('neighbouring spheres touch' in q, 'Touching-sphere assumption not stated')\n    given = re.search(r'effective refractive index of ([\\d.]+) for the film', q)\n    if given:\n        return float(given.group(1))\n    ns = float(find(r'spheres have refractive index ([\\d.]+)', q, 'Sphere index missing').group(1))\n    nm = float(find(r'medium of refractive index ([\\d.]+)', q, 'Medium index missing').group(1))\n    need('volume-weighted average of the squared refractive indices' in q, 'Effective-medium rule missing')\n    f = (math.pi / 6) * lat['nn'] ** 3 / lat['volume']\n    return math.sqrt(f * ns * ns + (1 - f) * nm * nm)\n\n\ndef opal_quantity(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    stated_conditions(q)\n    lat = analyse(spheres(packet['inputs'][0]))\n    d111 = 2 * math.pi / lat['g'][0]\n    if 'What is the sphere diameter' in q:\n        need('neighbouring spheres touch' in q, 'Touching-sphere assumption not stated')\n        value = lat['nn']\n    elif 'close-packed (most densely populated) planes' in q:\n        value = d111\n    elif 'conventional cubic unit cell' in q:\n        need(lat['fcc'], 'Lattice is not face-centred cubic')\n        value = (4 * lat['volume']) ** (1 / 3)\n    else:\n        need('close-packed planes parallel to the film surface' in q, 'Film orientation not stated')\n        n = optics(q, lat)\n        if 'At what angle of incidence' in q:\n            lam = float(find(r'vacuum wavelength of ([\\d.]+) nm', q, 'Target wavelength missing').group(1))\n            s = n * n - (lam / (2 * d111)) ** 2\n            need(0 < s < 1, 'Target wavelength not reachable')\n            value = math.degrees(math.asin(math.sqrt(s)))\n        else:\n            need('first-order Bragg reflection' in q, 'Unknown quantity')\n            m = re.search(r'incident from air at ([\\d.]+)° from the film normal', q)\n            need(m is not None or 'incident along the film normal' in q, 'Incidence not stated')\n            theta = math.radians(float(m.group(1))) if m else 0.0\n            value = 2 * d111 * math.sqrt(n * n - math.sin(theta) ** 2)\n    return dict(judge_numeric(packet, key, value), parameters=dict(nn_nm=lat['nn'], d111_nm=d111), method='reciprocal lattice; Bragg-Snell')\n\n\ndef opal_design(packet, key):\n    same_as_asset(packet, key)\n    q = packet['question']\n    stated_conditions(q)\n    lam = {}\n    size = {}\n    for inp in packet['inputs']:\n        lat = analyse(spheres(inp))\n        n = optics(q, lat)\n        lam[inp['name']] = 2 * (2 * math.pi / lat['g'][0]) * n\n        size[inp['name']] = lat['nn']\n    need('normal-incidence' in q, 'Incidence not stated')\n    closest = re.search(r'close-packed planes is closest to ([\\d.]+) nm', q)\n    below = re.search(r'stays below ([\\d.]+) nm', q)\n    need((closest is None) != (below is None), 'Design goal not stated exactly once')\n    if closest:\n        t = float(closest.group(1))\n        ranked = sorted(lam, key=lambda k: abs(lam[k] - t))\n        need(abs(lam[ranked[1]] - t) > abs(lam[ranked[0]] - t) + 1e-6, 'Tie for closest candidate')\n        winner = ranked[0]\n    else:\n        t = float(below.group(1))\n        ok = [k for k in lam if lam[k] < t]\n        need(ok, 'No candidate satisfies the limit')\n        winner = max(ok, key=lambda k: size[k])\n    hits = [o['label'] for o in packet['options'] if o['value'].endswith('(%s)' % winner)]\n    need(len(hits) == 1 and len({o['value'] for o in packet['options']}) == 4, 'Winner not named by exactly one distinct option')\n    for o in packet['options']:\n        name = re.search(r'\\((\\S+\\.xyz)\\)$', o['value'])\n        need(name is not None and name.group(1) in lam, 'Option does not name a supplied file')\n    need(key['correct_label'] == hits[0], 'Key label disagrees with recomputed choice')\n    return dict(label=hits[0], parameters=dict(peaks_nm=lam), method='per-file reciprocal lattice; Bragg-Snell; goal rule')\n\n\nCHECKERS.update(opal_geometry=opal_quantity, opal_bragg=opal_quantity, opal_design=opal_design)\n",
  "verify_all.py": "\"\"\"Run the independent checkers over every instance of a batch. No model calls.\n\nInput: a family run directory (student-packets.json + private-answers.json) or the\npublished workbench JSON. Exit status 1 if any instance fails, so a batch with a\nsingle disagreement cannot be exported.\n\npython verify_all.py --run runs/family-pilot-v01 --out runs/family-pilot-v01-independent-check.json\npython verify_all.py --workbench docs/data/family-workbench.json --out docs/data/independent-check.json\n\"\"\"\nimport argparse\nimport hashlib\nimport json\nimport sys\nfrom collections import Counter\nfrom pathlib import Path\n\nimport checkers\n\nROOT = Path(__file__).resolve().parent\n\n\ndef rehydrate(packets):\n    \"\"\"Published workbench inputs larger than ~40 kB are stored as {url, sha256} pointing at the\n    committed asset; restore the text and check the hash.\"\"\"\n    for packet in packets:\n        for item in packet.get('inputs', []):\n            if 'text' not in item and 'url' in item:\n                raw = (ROOT / 'docs' / item['url']).read_bytes()\n                if hashlib.sha256(raw).hexdigest() != item['sha256']:\n                    raise ValueError('Referenced input hash mismatch: ' + item['url'])\n                item['text'] = raw.decode('utf-8')\n    return packets\n\n\ndef load(run=None, workbench=None):\n    if run:\n        run = Path(run)\n        read = lambda n: json.loads((run / n).read_text(encoding='utf-8'))\n        return read('student-packets.json'), read('private-answers.json'), dict(source=str(run.name))\n    data = json.loads(Path(workbench).read_text(encoding='utf-8'))\n    return rehydrate(data['student_packets']), data['teacher_answers'], dict(source=Path(workbench).name, run=data['run'])\n\n\ndef verify(packets, keys, origin):\n    keys = {k['id']: k for k in keys}\n    missing = sorted(set(keys) ^ {p['id'] for p in packets})\n    results = [checkers.check(p, keys[p['id']]) if p['id'] in keys else\n               dict(id=p['id'], family=p['family'], status='fail', problem='No answer key') for p in packets]\n    results += [dict(id=i, family=keys[i]['family'], status='fail', problem='Answer key without packet')\n                for i in missing if i in keys]\n    by_family = {}\n    for r in results:\n        f = by_family.setdefault(r['family'], Counter())\n        f[r['status']] += 1\n    code = sorted((ROOT / 'checkers').glob('*.py')) + [Path(__file__)]\n    return dict(kind='independent_check', checker_version=checkers.VERSION, origin=origin,\n                checked=len(results), passed=sum(r['status'] == 'pass' for r in results),\n                failed=[dict(id=r['id'], problem=r['problem']) for r in results if r['status'] != 'pass'],\n                by_family={k: dict(v) for k, v in by_family.items()},\n                checker_sha256={str(p.relative_to(ROOT)).replace('\\\\', '/'): hashlib.sha256(p.read_bytes()).hexdigest()\n                                for p in code},\n                model_calls=0,\n                scope='Checks input→output, all four options, key agreement, answer-key leakage and source hashes. '\n                      'It does not judge scientific meaning or source interpretation; those remain sampled human/model review.',\n                results=results)\n\n\nif __name__ == '__main__':\n    p = argparse.ArgumentParser(description=__doc__)\n    group = p.add_mutually_exclusive_group(required=True)\n    group.add_argument('--run', type=Path)\n    group.add_argument('--workbench', type=Path)\n    p.add_argument('--out', type=Path, required=True)\n    a = p.parse_args()\n    if a.out.resolve().is_relative_to((ROOT / 'runs').resolve()) and a.out.exists():\n        raise SystemExit('Refusing to overwrite a file under runs/')\n    report = verify(*load(a.run, a.workbench))\n    a.out.write_text(json.dumps(report, ensure_ascii=False, indent=1) + '\\n', encoding='utf-8', newline='\\n')\n    print(json.dumps(dict(checked=report['checked'], passed=report['passed'], failed=report['failed']), ensure_ascii=False))\n    sys.exit(0 if report['passed'] == report['checked'] else 1)\n"
 }
}
