"""Inspect the E-MTAB-5009 count table and sample metadata.""" from pathlib import Path import pandas as pd PROJECT_ROOT = Path(__file__).resolve().parents[1] DATA_DIR = PROJECT_ROOT / "data" / "raw" / "E-MTAB-5009" COUNTS_PATH = DATA_DIR / "WP2_100acc.htseq.txt" METADATA_PATH = DATA_DIR / "E-MTAB-5009.sdrf.txt" def inspect_counts() -> None: # The first field in each data row is a gene ID. Its header cell is absent, # so index_col=0 prevents the gene IDs from being mistaken for counts. counts = pd.read_csv(COUNTS_PATH, sep="\t", index_col=0) counts.index.name = "gene_id" library_sizes = counts.sum(axis=0) print("COUNT TABLE") print(f"Path: {COUNTS_PATH}") print(f"Shape: {counts.shape[0]:,} genes x {counts.shape[1]:,} count columns") print(f"Duplicate gene IDs: {counts.index.duplicated().sum():,}") print(f"Duplicate column names: {counts.columns.duplicated().sum():,}") print(f"Missing values: {counts.isna().sum().sum():,}") print(f"Smallest count: {counts.min().min():,}") print(f"Largest count: {counts.max().max():,}") print(f"Genes with zero counts in every column: {(counts.sum(axis=1) == 0).sum():,}") print( "Library sizes (min / median / max): " f"{library_sizes.min():,.0f} / " f"{library_sizes.median():,.0f} / " f"{library_sizes.max():,.0f}" ) print("\nFirst 5 genes and first 5 count columns:") print(counts.iloc[:5, :5].to_string()) def inspect_metadata() -> None: metadata = pd.read_csv(METADATA_PATH, sep="\t") # One assay can occupy multiple SDRF rows because paired-end reads and # sequencing lanes are described separately. Deduplicate before counting # biological assays and conditions. assays = metadata.drop_duplicates(subset="Assay Name") print("\nMETADATA") print(f"Path: {METADATA_PATH}") print(f"Raw metadata shape: {metadata.shape[0]:,} rows x {metadata.shape[1]:,} columns") print(f"Unique assays: {assays['Assay Name'].nunique():,}") print(f"Unique ecotypes: {assays['Factor Value[ecotype]'].nunique():,}") print("Unique assays by condition:") print(assays["Factor Value[environmental stress]"].value_counts().to_string()) print(f"Missing cells in metadata: {metadata.isna().sum().sum():,}") print("\nSelected metadata columns for the first 5 unique assays:") selected = [ "Assay Name", "Factor Value[ecotype]", "Factor Value[environmental stress]", "Factor Value[block]", ] print(assays[selected].head().to_string(index=False)) def main() -> None: for required_path in (COUNTS_PATH, METADATA_PATH): if not required_path.exists(): raise FileNotFoundError( f"Missing {required_path}. Run scripts/download_data.ps1 first." ) inspect_counts() inspect_metadata() if __name__ == "__main__": main()