Source code for pyexpressionatlas.models

"""Data models for Expression Atlas."""

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
from typing import Any

from biocframe import BiocFrame


[docs] class ExperimentType(str, Enum): """Valid Expression Atlas experiment types.""" TRANSCRIPTION_PROFILING_ARRAY = "transcription profiling by array" MICRORNA_PROFILING_ARRAY = "microRNA profiling by array" ANTIGEN_PROFILING = "antigen profiling" PROTEOMIC_PROFILING = "proteomic profiling by mass spectrometer" RNASEQ_CODING = "RNA-seq of coding RNA" RNASEQ_NONCODING = "RNA-seq of non coding RNA" RNASEQ_TOTAL = "RNA-seq of total RNA" RNASEQ_SINGLE_CELL_CODING = "RNA-seq of coding RNA from single cells" RNASEQ_SINGLE_CELL_NONCODING = "RNA-seq of non coding RNA from single cells"
[docs] @classmethod def is_rnaseq(cls, exp_type: str) -> bool: """Check if experiment type is RNA-seq.""" return "rna-seq" in exp_type.lower()
[docs] @classmethod def is_microarray(cls, exp_type: str) -> bool: """Check if experiment type is microarray.""" return "array" in exp_type.lower()
[docs] @classmethod def get_eligible_types(cls) -> list[str]: """Return list of all eligible experiment type values.""" return [e.value for e in cls]
[docs] @dataclass class SearchResult: """Container for search results from BioStudies API.""" accession: str species: str | None experiment_type: str | None title: str | None connection_error: bool = False
[docs] def to_dict(self) -> dict[str, Any]: """Convert to dictionary.""" return { "Accession": self.accession, "Species": self.species, "Type": self.experiment_type, "Title": self.title, }
[docs] def search_results_to_biocframe(results: list[SearchResult]) -> BiocFrame: """Convert list of SearchResult objects to a BiocFrame.""" columns = ["Accession", "Species", "Type", "Title"] if not results: return BiocFrame({col: [] for col in columns}, column_names=columns) valid_results = [r for r in results if not r.connection_error] # Sort by Species, Type, then Accession (matching R package behavior) valid_results.sort( key=lambda r: ( r.species if r.species is not None else "", r.experiment_type if r.experiment_type is not None else "", r.accession, ) ) data = {col: [] for col in columns} for r in valid_results: d = r.to_dict() for col in columns: data[col].append(d[col]) return BiocFrame(data, column_names=columns)