Skip to content

Commit 554c1cf

Browse files
authored
Merge pull request #23 from broadinstitute/dp-fix
Fix TSV delimiter bug and add CI validation
2 parents 8981a68 + b007f25 commit 554c1cf

3 files changed

Lines changed: 124 additions & 1 deletion

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Validate assembly/reference_genomes.tsv structure.
4+
5+
This file has no header row and expects exactly 4 tab-separated columns:
6+
1. tax_id (integer)
7+
2. short_name (string, may be empty)
8+
3. description (string)
9+
4. accessions (colon-separated list of accession IDs)
10+
"""
11+
12+
import sys
13+
import csv
14+
from pathlib import Path
15+
16+
17+
def validate_reference_genomes_tsv(tsv_file: Path) -> bool:
18+
"""
19+
Validate that the reference_genomes.tsv file has proper structure:
20+
- Tab-separated values (not spaces)
21+
- Exactly 4 columns in every row
22+
- tax_id is a valid integer
23+
- accessions field is not empty
24+
"""
25+
EXPECTED_COLUMNS = 4
26+
errors = []
27+
28+
print(f"Validating reference genomes TSV: {tsv_file}")
29+
30+
with open(tsv_file, 'r', encoding='utf-8') as f:
31+
reader = csv.reader(f, delimiter='\t')
32+
33+
for row_num, row in enumerate(reader, start=1):
34+
# Skip empty rows
35+
if not row or all(cell.strip() == '' for cell in row):
36+
continue
37+
38+
# Check column count
39+
if len(row) != EXPECTED_COLUMNS:
40+
errors.append(
41+
f"Line {row_num}: Expected {EXPECTED_COLUMNS} columns, found {len(row)}. "
42+
f"This may indicate spaces were used instead of tabs."
43+
)
44+
# Show a preview of what was parsed
45+
if len(row) == 1 and ' ' in row[0]:
46+
errors.append(
47+
f" Hint: Line appears to use spaces instead of tabs as delimiters."
48+
)
49+
continue
50+
51+
tax_id, short_name, description, accessions = row
52+
53+
# Validate tax_id is an integer
54+
tax_id = tax_id.strip()
55+
if not tax_id:
56+
errors.append(f"Line {row_num}: tax_id (column 1) is empty")
57+
else:
58+
try:
59+
int(tax_id)
60+
except ValueError:
61+
errors.append(f"Line {row_num}: tax_id '{tax_id}' is not a valid integer")
62+
63+
# Validate accessions is not empty
64+
accessions = accessions.strip()
65+
if not accessions:
66+
errors.append(f"Line {row_num}: accessions (column 4) is empty")
67+
68+
if errors:
69+
print(f"\nERROR: Found {len(errors)} validation issue(s):\n")
70+
for error in errors:
71+
print(f" {error}")
72+
return False
73+
74+
print(f"Validation passed: All rows have {EXPECTED_COLUMNS} tab-separated columns")
75+
return True
76+
77+
78+
def main():
79+
if len(sys.argv) != 2:
80+
print("Usage: python validate_reference_genomes_tsv.py <tsv_file>")
81+
sys.exit(1)
82+
83+
tsv_file = Path(sys.argv[1])
84+
if not tsv_file.exists():
85+
print(f"ERROR: File not found: {tsv_file}")
86+
sys.exit(1)
87+
88+
if not validate_reference_genomes_tsv(tsv_file):
89+
sys.exit(1)
90+
91+
92+
if __name__ == "__main__":
93+
main()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Validate Reference Genomes TSV
2+
3+
on:
4+
push:
5+
paths:
6+
- 'assembly/reference_genomes.tsv'
7+
pull_request:
8+
paths:
9+
- 'assembly/reference_genomes.tsv'
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
validate:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v4
25+
with:
26+
python-version: '3.11'
27+
28+
- name: Validate TSV structure (4 tab-separated columns)
29+
run: |
30+
python .github/scripts/validate_reference_genomes_tsv.py assembly/reference_genomes.tsv

assembly/reference_genomes.tsv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
93838 A Influenza A virus (A/goose/Guangdong/1/1996(H5N1)) NC_007357.1:NC_007358.1:NC_007359.1:NC_007362.1:NC_007360.1:NC_007361.1:NC_007363.1:NC_007364.1
1616
93838 A Influenza A virus (A/Bovine/texas/24-029328-01/2024(H5N1)) PP599462.1:PP599463.1:PP599464.1:PP599465.1:PP599466.1:PP599467.1:PP599468.1:PP599469.1
1717
465975 A Influenza A virus (A/Washington/2148/2025(H5N5)) PX508207.1:PX508206.1:PX508205.1:PX508201.1:PX508203.1:PX508208.1:PX508202.1:PX508204.1
18-
329376 A Influenza A virus (A/Yunnan/0127/2015(H5N6)) KT245150.1:KT245149.1:KT245148.1:KT245143.1:KT245146.1:KT245145.1:KT245144.1:KT245147.1
18+
329376 A Influenza A virus (A/Yunnan/0127/2015(H5N6)) KT245150.1:KT245149.1:KT245148.1:KT245143.1:KT245146.1:KT245145.1:KT245144.1:KT245147.1
1919
119215 A Influenza A virus (A/Mexico/InDRE7218/2012(H7N3)) CY125725.1:CY125726.1:CY125727.1:CY125728.1:CY125729.1:CY125730.1:CY125731.1:CY125732.1
2020
325678 A Influenza A virus (A/Jiangsu/1/2018(H7N4)) MG779873.1:MG779874.1:MG779875.1:MG779876.1:MG779877.1:MG779878.1:MG779879.1:MG779880.1
2121
1332244 A Influenza A virus (A/Shanghai/02/2013(H7N9)) NC_026422.1:NC_026423.1:NC_026424.1:NC_026425.1:NC_026426.1:NC_026429.1:NC_026427.1:NC_026428.1

0 commit comments

Comments
 (0)