File size: 4,572 Bytes
1ea7ba6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | """
analyze_rice_overlap.py — resolve the P2 rice go/no-go gate ON PAPER (no images).
The rice cross-source benchmark hinges on whether varieties overlap across sources
of different acquisition style — especially whether the only genuinely IN-THE-WILD
set (D5 BDRice) shares varieties with the studio/microscope sets. Overlap is a
NAME-mapping question, so we can answer it now from the variety lists in
outputs/recon_rice.md, before downloading anything.
Variety lists verified by the rice-data scout (outputs/recon_rice.md, 2026-06-22).
Edit CONFIDENT / FUZZY as the manual mapping table (rice analog of spice class
normalization). This file IS the seed of outputs/rice_class_map.
python analyze_rice_overlap.py
"""
from itertools import combinations
ACQ = { # acquisition style per source (the axis ARC-V tests)
"D2_aruzz": "studio", "D4_riceseed": "studio",
"D5_bdrice": "WILD", "D6_prbd": "microscope", "D1_koklu": "studio(TR)",
}
VARIETIES = {
"D1_koklu": ["Arborio", "Basmati", "Ipsala", "Jasmine", "Karacadag"],
"D2_aruzz": ["Subol Lota", "Bashmoti (Deshi)", "Ganjiya", "Shampakatari",
"Sugandhi Katarivog", "BR-28", "BR-29", "Paijam", "Bashful",
"Lal Aush", "BR-Jirashail", "Gutisharna", "Birui", "Najirshail",
"Pahari Birui", "Polao (Katari)", "Polao (Chinigura)", "Amon",
"Shorna-5", "Lal Binni"],
"D4_riceseed": ["25", "28", "29", "89", "100", "Chinigura", "Kata Irri", "Kata Irri Vog"],
"D5_bdrice": ["Haski", "Nabil", "Mozumder", "Utsob Nazir", "Mizan", "Atash",
"Pyzam", "Mozammel-Miniket"],
"D6_prbd": ["Aush", "Beroi", "BR-28", "BR-29", "Ghee Bhog", "Katari Nazir",
"Katari Siddho", "Swarna", "Miniket", "Chinigura"],
}
# CONFIDENT: documented same cultivar (datasheets / standard BD nomenclature).
CONFIDENT = {
"28": "br28", "br-28": "br28", "29": "br29", "br-29": "br29",
"chinigura": "chinigura", "polao (chinigura)": "chinigura",
"miniket": "miniket", "mozammel-miniket": "miniket", # brand 'X-Miniket' = Miniket grade
}
# FUZZY: plausible same cultivar pending datasheet/photo check (spelling/brand variants).
FUZZY = {
"pyzam": "paijam", "paijam": "paijam", # Pyzam/Pajam/Paijam spelling variants
"utsob nazir": "nazir", "najirshail": "nazir", "katari nazir": "nazir",
}
# D5 (wild) brand names with UNKNOWN underlying cultivar — these gate extra overlap.
UNRESOLVED_D5 = ["Haski", "Nabil", "Mozumder", "Mizan", "Atash"]
def norm(raw, fuzzy):
k = raw.strip().lower()
if k in CONFIDENT:
return CONFIDENT[k]
if fuzzy and k in FUZZY:
return FUZZY[k]
return k # unmapped -> stays distinct
def canon(src, fuzzy):
return {norm(v, fuzzy) for v in VARIETIES[src]}
def report(fuzzy):
tag = "CONFIDENT+FUZZY" if fuzzy else "CONFIDENT-only"
print(f"\n{'='*66}\n OVERLAP [{tag}]\n{'='*66}")
bd = ["D2_aruzz", "D4_riceseed", "D6_prbd"] # the studio+microscope BD core
core = set.intersection(*[canon(s, fuzzy) for s in bd])
print(f" studio+microscope core ∩(D2,D4,D6) = {sorted(core)} (n={len(core)})")
studio_micro_union = set().union(*[canon(s, fuzzy) for s in bd])
d5 = canon("D5_bdrice", fuzzy)
wild_overlap = d5 & studio_micro_union
print(f" WILD (D5) ∩ (D2∪D4∪D6) = {sorted(wild_overlap)} (n={len(wild_overlap)}) <-- the headline gate")
for tok in sorted(wild_overlap):
where = [s for s in bd if tok in canon(s, fuzzy)]
d5raw = [v for v in VARIETIES["D5_bdrice"] if norm(v, fuzzy) == tok]
print(f" {tok:10s}: D5{d5raw} ↔ {where}")
# specifically D5 vs each studio set (the true studio-vs-wild contrast)
for s in ("D2_aruzz", "D4_riceseed"):
ov = d5 & canon(s, fuzzy)
print(f" WILD (D5) ∩ {s} [{ACQ[s]}] = {sorted(ov)} (n={len(ov)})")
if __name__ == "__main__":
print("Rice cross-source variety-overlap analysis (names only; no images)")
print("acquisition styles:", ACQ)
for fuzzy in (False, True):
report(fuzzy)
print(f"\n{'='*66}")
print("GATE: extra D5(wild) overlap is hidden behind these unmapped brand names")
print(f" -> resolve via the BDRice datasheet/paper, NOT pixels: {UNRESOLVED_D5}")
print("If >=2 of these map to BR-28/BR-29/Chinigura, the studio-vs-wild")
print("headline (>=3 shared, wild vs studio) is fully viable.")
|