917eedffcf
Main / Python 3.11 - Docs (push) Has been cancelled
Main / Python 3.11 - Build (push) Has been cancelled
Main / Python 3.11 - Lint (push) Has been cancelled
Main / Python 3.11 - Style (push) Has been cancelled
Main / Python 3.11 - Test (push) Has been cancelled
Main / GPU CI (push) Has been cancelled
Main / Release (push) Has been cancelled
Main / Build and Push Docker Images (push) Has been cancelled
169 lines
5.2 KiB
Python
169 lines
5.2 KiB
Python
"""
|
|
Split table tests with multiple relationships into individual tests.
|
|
|
|
For example, if you have a test case with cell=X, up=Y, down=Z, this script
|
|
will split it into two cases: one with cell=X, up=Y and another with cell=X, down=Z.
|
|
|
|
Usage:
|
|
python split_table_tests.py input.jsonl output.jsonl
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from olmocr.bench.tests import BasePDFTest, TableTest, TestType, load_tests
|
|
|
|
# The relationship fields that can be split
|
|
RELATIONSHIP_FIELDS = ["up", "down", "left", "right", "top_heading", "left_heading"]
|
|
|
|
|
|
def base_test_to_dict(test: BasePDFTest) -> dict:
|
|
"""
|
|
Convert any BasePDFTest to a dict by extracting all non-None attributes.
|
|
"""
|
|
from dataclasses import fields, is_dataclass
|
|
|
|
result = {}
|
|
if is_dataclass(test):
|
|
for field in fields(test):
|
|
value = getattr(test, field.name)
|
|
# Skip None values and empty strings for optional fields
|
|
if value is not None and value != "":
|
|
result[field.name] = value
|
|
return result
|
|
|
|
|
|
def test_to_dict_minimal(test: TableTest) -> dict:
|
|
"""
|
|
Convert a TableTest to a dict, removing empty relationship fields.
|
|
"""
|
|
result = {
|
|
"pdf": test.pdf,
|
|
"page": test.page,
|
|
"id": test.id,
|
|
"type": test.type,
|
|
"max_diffs": test.max_diffs,
|
|
"cell": test.cell,
|
|
}
|
|
|
|
# Only include non-empty relationship fields
|
|
for field in RELATIONSHIP_FIELDS:
|
|
value = getattr(test, field)
|
|
if value and value.strip():
|
|
result[field] = value
|
|
|
|
# Include other optional fields if set
|
|
if test.checked is not None:
|
|
result["checked"] = test.checked
|
|
if test.url:
|
|
result["url"] = test.url
|
|
if test.ignore_markdown_tables:
|
|
result["ignore_markdown_tables"] = test.ignore_markdown_tables
|
|
|
|
return result
|
|
|
|
|
|
def split_table_test(test: TableTest) -> list[dict]:
|
|
"""
|
|
Split a single TableTest with multiple relationships into separate test dicts.
|
|
|
|
Each resulting test will have only one relationship field set (plus the cell).
|
|
|
|
Args:
|
|
test: The TableTest to split
|
|
|
|
Returns:
|
|
A list of dicts, one for each non-empty relationship
|
|
"""
|
|
# Find which relationship fields are set (non-empty)
|
|
active_relationships = []
|
|
for field in RELATIONSHIP_FIELDS:
|
|
value = getattr(test, field)
|
|
if value and value.strip():
|
|
active_relationships.append((field, value))
|
|
|
|
# If there's 0 or 1 relationship, no splitting needed - return as minimal dict
|
|
if len(active_relationships) <= 1:
|
|
return [test_to_dict_minimal(test)]
|
|
|
|
# Create a new test dict for each relationship
|
|
split_tests = []
|
|
for field, value in active_relationships:
|
|
result = {
|
|
"pdf": test.pdf,
|
|
"page": test.page,
|
|
"id": f"{test.id}_{field}",
|
|
"type": test.type,
|
|
"max_diffs": test.max_diffs,
|
|
"cell": test.cell,
|
|
field: value, # Only include the single relationship field
|
|
}
|
|
|
|
# Include other optional fields if set
|
|
if test.checked is not None:
|
|
result["checked"] = test.checked
|
|
if test.url:
|
|
result["url"] = test.url
|
|
if test.ignore_markdown_tables:
|
|
result["ignore_markdown_tables"] = test.ignore_markdown_tables
|
|
|
|
split_tests.append(result)
|
|
|
|
return split_tests
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Split table tests with multiple relationships into individual tests")
|
|
parser.add_argument("input_file", help="Input JSONL file containing tests")
|
|
parser.add_argument("output_file", help="Output JSONL file for split tests")
|
|
parser.add_argument("--keep-non-table", action="store_true", help="Keep non-table tests in the output (default: only output table tests)")
|
|
|
|
args = parser.parse_args()
|
|
|
|
input_path = Path(args.input_file)
|
|
output_path = Path(args.output_file)
|
|
|
|
if not input_path.exists():
|
|
print(f"Error: Input file {input_path} does not exist")
|
|
sys.exit(1)
|
|
|
|
# Load all tests
|
|
print(f"Loading tests from {input_path}...")
|
|
tests = load_tests(str(input_path))
|
|
print(f"Loaded {len(tests)} tests")
|
|
|
|
# Process tests
|
|
output_tests = []
|
|
table_tests_count = 0
|
|
split_count = 0
|
|
|
|
for test in tests:
|
|
if test.type == TestType.TABLE.value:
|
|
table_tests_count += 1
|
|
split_dicts = split_table_test(test)
|
|
if len(split_dicts) > 1:
|
|
split_count += 1
|
|
print(f"Split test '{test.id}' into {len(split_dicts)} tests")
|
|
output_tests.extend(split_dicts)
|
|
elif args.keep_non_table:
|
|
# For non-table tests, just convert to dict (keep all fields)
|
|
output_tests.append(base_test_to_dict(test))
|
|
|
|
# Save output
|
|
print(f"\nSaving {len(output_tests)} tests to {output_path}...")
|
|
with open(output_path, "w") as f:
|
|
for test_dict in output_tests:
|
|
f.write(json.dumps(test_dict) + "\n")
|
|
|
|
print("\nSummary:")
|
|
print(f" Input tests: {len(tests)}")
|
|
print(f" Table tests found: {table_tests_count}")
|
|
print(f" Table tests split: {split_count}")
|
|
print(f" Output tests: {len(output_tests)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|