scigantic-nci
Analysis-ready NCI cancer data in one import: per-project Genomic Data Commons tables (clinical, RNA-Seq, mutations, copy number, miRNA, RPPA, methylation) and per-collection Imaging Data Commons indexes with sample DICOM, read as pandas DataFrames from public S3 or a mounted copy. No account, no download step, no BigQuery.
import scigantic_nci as nci
nci.gdc.projects() # one row per mirrored GDC project
clin = nci.gdc.clinical("TCGA-BLCA") # 412 cases: os_time_days, os_event, stage
tpm = nci.gdc.expression("TCGA-BLCA", genes=["TP53", "ESR1"], sample_type="Primary Tumor") # (2, 412)
maf = nci.gdc.mutations("TCGA-BLCA", genes=["TP53"], non_silent=True) # MAF rows
freq = nci.gdc.mutation_frequency("TCGA-BLCA") # TP53 0.488, TTN 0.425, KMT2D 0.263, ...
nci.idc.collections() # 176 collections, 1,032,911 series
s = nci.idc.series("tcga_lihc", modality="CT") # 777 rows, one per DICOM series
vol = nci.idc.read_sample("tcga_lihc", "CT") # Volume (36, 512, 512) in HU, from the mirror
nci.idc.pull_series(s.iloc[0], "/tmp/ct") # the full series from idc-open-data, anonymous
Installation
$ pip install scigantic-nci
$ pip install "scigantic-nci[dicom]" # pydicom and the pylibjpeg decoders, for read_sample() and pulled series
Python 3.10 or newer. Dependencies are pandas, pyarrow, numpy and boto3.
Why this exists
Both NCI data commons are public on S3, and both are stored in a way that no one can use without an index they do not ship.
The GDC's open buckets (tcga-2-open, gdc-cptac-phs001287-2-open, ...) hold one folder per file, named by the file's UUID: every key is <file_id>/<file_name>, with nothing above it for program, project, case or data type. Across the 73 projects with open files that is 390,418 folders; the 33 TCGA projects alone are 284,498. Which of those folders belong to TCGA-BLCA is only knowable through the GDC API, and every folder holds one per-sample file: TCGA-BRCA has 1,231 Gene Expression Quantification TSVs, one per aliquot, each listing the same 60,660 genes, so its expression matrix is 1,231 downloads followed by a column-wise stack. The newer GDC objects are also encrypted with SSE-KMS and refuse anonymous reads.
The IDC's buckets (idc-open-data, idc-open-data-cr, idc-open-data-two) hold 1,032,911 DICOM series across 176 collections, 96.9 TB, at s3://<bucket>/<crdc_series_uuid>/<instance_uuid>.dcm. The key carries no collection, patient or modality; that mapping is the IDC index, served from BigQuery or the idc-index package's downloadable tables.
This package reads two Scigantic mirrors that hold those indexes and the analysis-ready tables:
s3://scigantic-gdc-open/<PROJECT>/: every open-access file of a project stacked into parquet tables, one prefix per project. The build so far covers 36 projects (the 33 TCGA projects and TARGET-ALL-P1, -P2, -P3): 13,230 cases, 1,178 tables, 4.97 GB of parquet, built from 168,844 source files (178.4 GB) read from the GDC buckets, at Data Release 46.0 (August 10, 2026). More projects are being added;gdc.projects()lists what is live.s3://scigantic-idc-open/<collection_id>/: for each of the 176 collections aseries,studiesandpatientstable (sm_seriesfor the 73 with slides,analysis_resultsfor 55, clinical tables for 59), plus sample DICOM that can be read without touching the raw buckets: 286 whole small radiology series and the thumbnail and two lowest pyramid levels of 47 slides, 20,897 files, 5.23 GB. Built from idc-index 0.12.5, IDC data v24.
Each prefix carries a README.md describing its tables and a BUILD_REPORT.json. For GDC the report records the source file count, files and bytes read, md5 checks against the GDC manifest, duplicates and any re-alignment (realigned_files); the tables are a re-arrangement of the GDC files with values unchanged from the source. For IDC the report records the series, patient and study counts, modalities, licenses and source DOIs of the collection and of every sample. Both mirrors were built on 2026-09-13.
What the functions do about size: column subsets and row filters are pushed down to parquet, so expression("TCGA-BRCA", genes=[5 symbols]) reads 5 x 1,231 values in 0.10 s instead of the 296 MB full matrix (0.37 s locally), and methylation(..., probes=[...]) reads only the 50,000-probe row groups whose statistics can contain those ids. The numbers are in docs/gdc.md.
Note on names: gdc.samples() is the GDC biospecimen table (one row per sample of a case); idc.samples() lists the sample DICOM series shipped with a collection. The two modules use the same word for different things because their sources do.
Data provenance and citation
GDC. Only the open-access tier is mirrored; it carries no access restrictions. Cite the program that generated the data (TCGA, TARGET, ...) and the GDC: Grossman et al., Toward a Shared Vision for Cancer Genomic Data, NEJM 2016, doi:10.1056/NEJMp1607591. TCGA and TARGET publication guidelines: https://www.cancer.gov/ccg/research/genome-sequencing/tcga/using-tcga-data/citing.
IDC. Every series carries its own license in series.parquet (license_short_name) and its source DOI (source_DOI); across the mirror 865,935 series are CC BY 4.0, 132,303 CC BY 3.0, 28,783 CC BY-NC 4.0, 5,851 CC BY-NC 3.0 and 39 under the National Library of Medicine terms. Collections can mix licenses, so check the row, not the collection. The CC BY-NC series (28,783 + 5,851) may not be used for commercial purposes; license_short_name is authoritative and the only place the license is recorded, so filter on it before using a series in commercial work. Cite the source DOIs (idc.report(c)["source_DOIs"], 237 distinct across the mirror) and the IDC: Fedorov et al., NCI Imaging Data Commons, Radiographics 2021, doi:10.1148/rg.2021210020; Fedorov et al., National Cancer Institute Imaging Data Commons: Toward Transparency, Reproducibility, and Scalability in Imaging Artificial Intelligence, Nature Methods 2023, doi:10.1038/s41592-023-01893-2.
This package's code is MIT-0. That does not extend to the data.
Public API
Every per-project or per-collection function takes the id first and root: str | None = None last. Walkthroughs with real output: docs/gdc.md, docs/idc.md.
scigantic_nci.gdc
| function | returns |
|---|---|
projects() |
one row per mirrored project (release, tables, cases, files and bytes read) |
report(p), tables(p), readme(p) |
build report dict, table sizes, README text |
manifest(p, data_type=None) |
every open-access file with bucket, key, md5 and HTTPS URL |
clinical(p, primary_only=True) |
cases joined to the primary diagnosis, with os_time_days, os_event, age_at_diagnosis_years, stage |
diagnoses, treatments, exposures, follow_ups, samples, aliquots |
the clinical tables as stored |
expression(p, genes, sample_type, kind, protein_coding, drop_par_y) |
genes x aliquots (TPM or counts), attrs["gene_id"] |
expression_samples(p), star_qc(p) |
column to case mapping, STAR summary rows |
mutations(p, genes, non_silent, columns) |
MAF rows, filters pushed down |
mutation_frequency(p, non_silent=True) |
fraction of tumor barcodes mutated per gene |
copy_number(p, workflow, genes) |
genes x tumor aliquots, attrs["workflow"], attrs["gene_location"] |
copy_number_workflows(p, kind), copy_number_samples(p, workflow) |
available workflows, column mapping |
segments(p, kind, workflow) |
long segment tables |
mirna(p, kind, sample_type), mirna_samples, mirna_isoforms |
miRNA matrices and tables |
rppa(p, sample_type), rppa_samples, rppa_antibodies |
RPPA matrix (attrs["agid"]) and tables |
methylation(p, platform, probes, columns, sample_type) |
probes x aliquots betas |
methylation_platforms(p), methylation_samples(p, platform) |
platforms, column mapping |
case_for_barcode(barcode) |
case id for TCGA and TARGET barcodes |
fetch_raw(row_or_project, file_id, dest) |
one raw GDC file, md5-verified |
scigantic_nci.idc
| function | returns |
|---|---|
collections(), collection_ids() |
one row per collection (cached), sorted ids |
report(c), tables(c), readme(c) |
build report dict, table sizes, README text |
series(c, modality, patient, max_size_mb, columns) |
series.parquet, filters pushed down |
studies(c), patients(c) |
studies.parquet, patients.parquet |
slides(c) |
sm_series joined to series, list columns flattened, stain column |
analysis_results(c) |
analysis_results.parquet or an empty frame |
clinical_tables(c), clinical(c, table), clinical_dictionary(c) |
clinical tables and their dictionary |
samples(c), sample_files(c, modality) |
sample series metadata, .dcm paths |
read_sample(c, modality) |
Volume or SlideLevels (needs the dicom extra) |
assemble_level(path) |
one WSI level as an array |
pull_series(row_or_uuid, dest, bucket) |
local .dcm paths from the raw bucket |
series_size(row_or_uuid), viewer_url(row) |
MB, IDC viewer link |
NciError is the base exception; NotMirroredError (a subclass) means the project, collection or table is not in the mirror and names what is.
Where the bytes come from
A project or collection is resolved to a place to read from, in this order:
- an explicit
rootargument (a local directory holding that prefix's files), $SCIGANTIC_NCI_ROOT/<bucket>/<key>or$SCIGANTIC_NCI_ROOT/<key>if that directory exists (local mirrors, tests),- the Scigantic notebook mount at
$SCIGANTIC_MOUNT_PATH(default/mnt/archive) when itsBUILD_REPORT.jsonnames the same project or collection, - the public bucket, read anonymously through pyarrow's S3 filesystem.
Anonymous S3 works because both mirror buckets are public-read; no credentials are required, and none are used even if present. The two exceptions are the raw NCI buckets: idc.pull_series reads idc-open-data* unsigned, and gdc.fetch_raw uses a signed default boto3 client because the newer GDC objects refuse unsigned reads, falling back to the GDC HTTPS download URL when S3 answers AccessDenied, 403 or 404 or no credentials are configured.
Limits
- No controlled-access data. Only the GDC open-access tier is mirrored; there are no BAMs, no germline calls and no controlled clinical supplements.
- Slides are not mirrored. GDC
Slide Imagefiles appear inmanifest()but not as tables (TCGA-BLCA alone lists 926 of them, 833 GB). IDC slide microscopy is insm_seriesandslides(), but the mirror keeps only the thumbnail and the two lowest pyramid levels of one slide per collection; full pyramids come throughpull_series. - Methylation is optional and large. The beta matrices are built only on request, so
methylation_platforms()is empty for most projects andmethylation()raisesNotMirroredError. Where present, a 450k matrix is 486,427 probes wide (486,427 x 45 for TCGA-CHOL); a 1,200-aliquot project read whole is about 2.3 GB in pandas, so passprobes,columnsorsample_type. - Copy-number samples table. In
copy_number_samples()thesample_typedescribes the matrix column's own aliquot, and every column is the tumor member of the tumor/normal pair the file was called on (in TCGA-BLCA all 392 ASCAT3 columns are primary tumor barcodes and all 392 rows say Primary Tumor). The paired workflows (ASCAT2, ASCAT3, AscatNGS) keep both aliquots of the pair pipe-joined inaliquot_submitter_id, in no fixed order. Tables built before 2026-09-13 reported the first aliquot of that pair instead, so 195 BLCA rows said Blood Derived Normal; the current tables do not. One gap remains: 82 AscatNGS columns in CGCI-BLGSP (67) and HCMI-CMDC (15) are themselves pipe-joined pairs, and theresample_typeis the pair's first aliquot. - Gene names are not unique. GENCODE v36 gives 67 names to more than one gene id (plus 44
_PAR_Yduplicates, dropped by default);expression()andcopy_number()keep the first and list the rest inattrs["dropped_duplicate_names"]. - Compressed DICOM needs a decoder. Slide levels are JPEG baseline and tomosynthesis is JPEG 2000; without a pydicom plugin
read_sample()raisesNciErrorwith the install hint. Thedicomextra installs them. - One collection has no sample:
b_mode_and_ceus_liver(120 US series);samples()is empty andread_sample()raisesValueError. - Which GDC projects are mirrored. All 57 open-access projects of GDC Data Release 46.0 are built and live;
gdc.projects()is the source of truth, and an unknown id raisesNotMirroredErrorlisting the mirrored ones.
What is not here
- Controlled-access GDC data of any kind.
- Raw sequencing reads (BAM, FASTQ) and the per-file TSVs themselves;
fetch_raw()gets one when needed. - Stranded RNA-Seq counts and FPKM (only
counts_unstrandedandtpm_unstrandedare stacked; the rest stays in the source TSVs listed in the manifest). - GDC slide images, and IDC pixel data beyond the per-collection samples.
- Methylation for projects built without it.
- Anything derived: no normalisation, batch correction, survival models or segmentations that are not in the source data.
Command line
scigantic-nci wraps the same functions; tables go to stdout as CSV, or to --out FILE.csv. --root maps to the root= argument. An id with a lowercase letter is an IDC collection, otherwise a GDC project. Library errors print to stderr with exit code 2.
$ scigantic-nci projects
$ scigantic-nci collections
$ scigantic-nci tables TCGA-BLCA
$ scigantic-nci readme tcga_lihc
$ scigantic-nci clinical TCGA-BLCA --out blca_clinical.csv
$ scigantic-nci expression TCGA-BLCA --genes TP53,ESR1 --sample-type "Primary Tumor" --counts
$ scigantic-nci mutations TCGA-BLCA --genes TP53,RB1 --non-silent
$ scigantic-nci mutation-frequency TCGA-BLCA --top 20
$ scigantic-nci series tcga_lihc --modality CT --max-size-mb 50
$ scigantic-nci sample tcga_lihc --modality CT
$ scigantic-nci viewer-url tcga_lihc --series-uid 1.3.6.1.4.1.14519.5.2.1.3344.4008.615841149820206875475663260335
$ scigantic-nci pull-series tcga_lihc --series-uid 1.3.6.1.4.1.14519.5.2.1.3344.4008.615841149820206875475663260335 --dest /tmp/ct
Real output of each command is in docs/cli.md.
Testing
The suite runs against a complete local copy of the mirrors when SCIGANTIC_NCI_ROOT points at one (tests/conftest.py skips otherwise) and asserts measured numbers: TCGA-BLCA has 412 cases, 431 RNA aliquots and 19 solid tissue normals; tcga_lihc has 3,457 series and 377 patients. Tests marked network read the public buckets (pytest -m "not network" to skip them). CI runs Python 3.10 through 3.14 plus mypy --strict.
License
MIT-0 for the code. See Data provenance and citation for the data.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scigantic_nci-0.1.1.tar.gz.
File metadata
- Download URL: scigantic_nci-0.1.1.tar.gz
- Upload date:
- Size: 50.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7c745c813173831befdb47ec8f74f31eaf455ef9fccc76177eb147920cf9cea
|
|
| MD5 |
5df91d3e5e2511061492b9bc15aad830
|
|
| BLAKE2b-256 |
65d95d33cb7346f453a7f44afeba3cab4b753f1f75368b30d921f672ebc8f4d5
|
File details
Details for the file scigantic_nci-0.1.1-py3-none-any.whl.
File metadata
- Download URL: scigantic_nci-0.1.1-py3-none-any.whl
- Upload date:
- Size: 36.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1be7a110c8b456b809b8970eb519ed5a459d60cfe08dc27911d4d10744990363
|
|
| MD5 |
46c405efd6d26482137b21f38a1b1aad
|
|
| BLAKE2b-256 |
d58d2db56624b5d297dc29c7b42fcd382df85aa68601cf3eb25e588afa020c81
|