Spaces:
Sleeping
Sleeping
Claude commited on
Commit ·
4ee95d7
1
Parent(s): 2d7fa7e
feat: persistent noise pattern exclusion — reject NON_STORY_TEXT to block on next OCR run
Browse files- smoke_signal_tab.py +53 -0
smoke_signal_tab.py
CHANGED
|
@@ -57,6 +57,48 @@ for d in [SOURCE_DIR, MANIFEST_CSV.parent, PROFILES_DIR, OCR_RAW_DIR,
|
|
| 57 |
d.mkdir(parents=True, exist_ok=True)
|
| 58 |
|
| 59 |
GOLD_FILE = GOLD_DIR / "gold_corrections.jsonl"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
DECISIONS_CSV = REVIEW_DIR / "review_decisions.csv"
|
| 61 |
QUEUE_CSV = REVIEW_DIR / "review_queue.csv"
|
| 62 |
BANNER_DATA_URI_FILE = Path(__file__).resolve().parent / "assets" / "smoke_signal_banner_data_uri.txt"
|
|
@@ -2371,6 +2413,13 @@ def run_ocr(page_selection: str = "", page_exclusion: str = "", replace_book_que
|
|
| 2371 |
method = "skipped-no-surya"
|
| 2372 |
|
| 2373 |
raw_text = " ".join(r["text"] for r in regions)[:500]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2374 |
corrected_text, punct_flags, punct_score = _apply_punctuation_corrections(
|
| 2375 |
raw_text,
|
| 2376 |
book_id,
|
|
@@ -2656,6 +2705,10 @@ def save_review_decision(idx: int, final_text: str, action: str, reviewer: str,
|
|
| 2656 |
}) + "\n")
|
| 2657 |
|
| 2658 |
learned_pairs = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2659 |
if action == "edited":
|
| 2660 |
learned_pairs = _record_punctuation_correction(
|
| 2661 |
raw_text_original,
|
|
|
|
| 57 |
d.mkdir(parents=True, exist_ok=True)
|
| 58 |
|
| 59 |
GOLD_FILE = GOLD_DIR / "gold_corrections.jsonl"
|
| 60 |
+
NOISE_DIR = SS_ROOT / "calibration" / "noise_patterns"
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _noise_path(book_id: str) -> Path:
|
| 64 |
+
NOISE_DIR.mkdir(parents=True, exist_ok=True)
|
| 65 |
+
return NOISE_DIR / f"{book_id}_noise.json"
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def _load_noise_patterns(book_id: str) -> list:
|
| 69 |
+
path = _noise_path(book_id)
|
| 70 |
+
if not path.exists():
|
| 71 |
+
return []
|
| 72 |
+
try:
|
| 73 |
+
return json.loads(path.read_text())
|
| 74 |
+
except Exception:
|
| 75 |
+
return []
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def _save_noise_pattern(book_id: str, pattern: str) -> None:
|
| 79 |
+
pattern = pattern.strip()
|
| 80 |
+
if not pattern or len(pattern) < 3:
|
| 81 |
+
return
|
| 82 |
+
patterns = _load_noise_patterns(book_id)
|
| 83 |
+
if pattern not in patterns:
|
| 84 |
+
patterns.append(pattern)
|
| 85 |
+
_noise_path(book_id).write_text(json.dumps(patterns, indent=2))
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def _text_matches_noise(text: str, patterns: list) -> bool:
|
| 89 |
+
if not patterns or not text:
|
| 90 |
+
return False
|
| 91 |
+
text_tokens = set(text.lower().split())
|
| 92 |
+
if not text_tokens:
|
| 93 |
+
return False
|
| 94 |
+
for pattern in patterns:
|
| 95 |
+
pat_tokens = set(pattern.lower().split())
|
| 96 |
+
if not pat_tokens:
|
| 97 |
+
continue
|
| 98 |
+
overlap = len(text_tokens & pat_tokens) / len(text_tokens)
|
| 99 |
+
if overlap >= 0.6:
|
| 100 |
+
return True
|
| 101 |
+
return False
|
| 102 |
DECISIONS_CSV = REVIEW_DIR / "review_decisions.csv"
|
| 103 |
QUEUE_CSV = REVIEW_DIR / "review_queue.csv"
|
| 104 |
BANNER_DATA_URI_FILE = Path(__file__).resolve().parent / "assets" / "smoke_signal_banner_data_uri.txt"
|
|
|
|
| 2413 |
method = "skipped-no-surya"
|
| 2414 |
|
| 2415 |
raw_text = " ".join(r["text"] for r in regions)[:500]
|
| 2416 |
+
|
| 2417 |
+
# Skip pages matching known noise patterns for this book
|
| 2418 |
+
_noise_pats = _load_noise_patterns(book_id)
|
| 2419 |
+
if _noise_pats and _text_matches_noise(raw_text, _noise_pats):
|
| 2420 |
+
log.append(log_line(f" ⊘ {book_id} p{page_num}: matched noise pattern — skipped"))
|
| 2421 |
+
continue
|
| 2422 |
+
|
| 2423 |
corrected_text, punct_flags, punct_score = _apply_punctuation_corrections(
|
| 2424 |
raw_text,
|
| 2425 |
book_id,
|
|
|
|
| 2705 |
}) + "\n")
|
| 2706 |
|
| 2707 |
learned_pairs = 0
|
| 2708 |
+
if action == "rejected" and str(reason).strip() == "NON_STORY_TEXT":
|
| 2709 |
+
noise_text = (final_text.strip() or raw_text.strip())
|
| 2710 |
+
if noise_text:
|
| 2711 |
+
_save_noise_pattern(str(item.get("book_id", "")), noise_text)
|
| 2712 |
if action == "edited":
|
| 2713 |
learned_pairs = _record_punctuation_correction(
|
| 2714 |
raw_text_original,
|