PlantPerturb-Small / scripts /inspect_data.py
aungkomyint's picture
Publish research draft and reproducible PCA-ridge benchmark
18410f0 verified
Raw History Blame Contribute Delete
2.92 kB
"""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()