"""G3: S1 floor, percentile against the same-size null, mandatory member floor (MMIN), optional W. Builds on gate2 (similarities, word test, k-means). On first import it samples the same-size null distribution of S1 and caches the sorted samples in null-samples.pkl. """ import bisect, pathlib, pickle, random import gate2 as g HERE = pathlib.Path(__file__).resolve().parent _path = HERE / 'null-samples.pkl' if _path.exists(): NULLS = pickle.loads(_path.read_bytes()) else: rnd, NULLS = random.Random(3033), {} for m in range(5, 151): need, samples = (1000 if m <= 60 else 200), [] while len(samples) < need: members = rnd.sample(range(g.n), m) if g.eligible(members): samples.append(g.cohesion(members)[0]) NULLS[m] = sorted(samples) _path.write_bytes(pickle.dumps(NULLS)) def percentile(s1, size): samples = NULLS[min(max(size, 5), 150)] return bisect.bisect_left(samples, s1) / len(samples) def signals(m): sig = g.signals(m) # size, stories, dominant, S1, Z1, MMIN, W, W_word, S6_old sig['PCT'] = percentile(sig['S1'], sig['size']) return sig def passes(sig, gate): if not (sig['size'] >= g.MIN_SIZE and sig['stories'] >= g.MIN_STORIES and sig['dominant'] <= g.MAX_DOMINANT): return False if sig['S1'] < gate['S1'] or sig['PCT'] < gate['PCT'] or sig['MMIN'] < gate['MMIN']: return False if gate.get('W') is not None and sig['W'] >= gate['W']: return False return True