Skill Tracer
Skills › Scientific Agent Skills › imaging-data-commons › index_tables_guide.md

index_tables_guide.md

205 lines · skills/imaging-data-commons/references/index_tables_guide.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Index Tables Guide for IDC
2
3**Tested with:** idc-index 0.12.5 (IDC data version v24)
4
5This guide covers the structure and access patterns for IDC index tables: programmatic schema discovery, DataFrame access, and join column references. For the overview of available tables and their purposes, see the "Index Tables" section in the main SKILL.md.
6
7**Complete index table documentation:** https://idc-index.readthedocs.io/en/latest/indices_reference.html
8

Index Tables Guide for IDC

Tested with: idc-index 0.12.5 (IDC data version v24)

This guide covers the structure and access patterns for IDC index tables: programmatic schema discovery, DataFrame access, and join column references. For the overview of available tables and their purposes, see the "Index Tables" section in the main SKILL.md.

Complete index table documentation: https://idc-index.readthedocs.io/en/latest/indices_reference.html

Raw lines 1 to 8
9## When to Use This Guide
11Load this guide when you need to:
12- Discover table schemas and column types programmatically
13- Access index tables as pandas DataFrames (not via SQL)
14- Understand key columns and join relationships between tables
16For SQL query examples (filter discovery, finding annotations, size estimation), see `references/sql_patterns.md`.

When to Use This Guide

Load this guide when you need to:

  • Discover table schemas and column types programmatically
  • Access index tables as pandas DataFrames (not via SQL)
  • Understand key columns and join relationships between tables

For SQL query examples (filter discovery, finding annotations, size estimation), see references/sql_patterns.md.

Raw lines 9 to 17
18## Prerequisites
20Needs `idc-index` installed — run `python scripts/check_version.py`, which reports the installed
21version and prints the install command for the interpreter you are running.

Prerequisites

Needs idc-index installed — run python scripts/check_version.py, which reports the installed version and prints the install command for the interpreter you are running.

Raw lines 18 to 22
Runs code python scripts/check_version.py :20
23## Available Tables
25`SKILL.md` carries a compact map of the table families. This is the full inventory with row
26granularity and contents. Always call `client.fetch_index("table_name")` before querying any
27of them — it is safe and idempotent for all tables, including those loaded automatically at
28startup.
30| Table | Row Granularity | Description |
31|-------|-----------------|-------------|
32| `index` | 1 row = 1 DICOM series | Primary metadata for all current IDC data |
33| `version_metadata_index` | 1 row = 1 IDC release version | IDC version release timestamps; join on `idc_version` to correlate series with their release date |
34| `collections_index` | 1 row = 1 collection | Collection-level metadata and descriptions |
35| `analysis_results_index` | 1 row = 1 analysis result collection | Metadata about derived datasets (annotations, segmentations) |
36| `clinical_index` | 1 row = 1 (collection, table, column) triple | Dictionary mapping clinical data table columns to collections |
37| `sm_index` | 1 row = 1 slide microscopy series | Slide Microscopy (pathology) series metadata |
38| `sm_instance_index` | 1 row = 1 slide microscopy instance | Instance-level (SOPInstanceUID) metadata for slide microscopy |
39| `seg_index` | 1 row = 1 DICOM Segmentation series | Segmentation metadata: algorithm, segment count, reference to source image series |
40| `ann_index` | 1 row = 1 DICOM ANN series | Microscopy Bulk Simple Annotations series metadata; references annotated image series |
41| `ann_group_index` | 1 row = 1 annotation group | Detailed annotation group metadata: graphic type, annotation count, property codes, algorithm |
42| `contrast_index` | 1 row = 1 series with contrast info | Contrast agent metadata: agent name, ingredient, administration route (CT, MR, PT, XA, RF) |
43| `volume_geometry_index` | 1 row = 1 CT/MR/PT series | 3D volume geometry validation for single-frame CT, MR, and PT series; boolean checks for orientation, spacing, dimensions, and slice positions; composite `regularly_spaced_3d_volume` flag |
44| `rtstruct_index` | 1 row = 1 RTSTRUCT series | RT Structure Set metadata: total ROI count, ROI names, generation algorithms, interpreted types, and the referenced image series UID |
45| `ct_index` | 1 row = 1 CT series | CT acquisition/reconstruction parameters: pixel spacing, slice thickness, kVp, convolution kernel, tube current (min/max for dose-modulated), exposure, spiral pitch, scan options |
46| `mr_index` | 1 row = 1 MR series | MR acquisition/sequence parameters: field strength, scanning sequence, TE (array for multi-echo), TR, flip angle, DiffusionBValue (array for DWI), pixel bandwidth, receive coil, number of temporal positions |
47| `pt_index` | 1 row = 1 PET series | PET acquisition/reconstruction/radiopharmaceutical parameters: series type, units, decay/scatter/attenuation correction, reconstruction method, radionuclide, injected dose, frame duration (array for dynamic PET) |
48| `prior_versions_index` | 1 row = 1 historical CRDC series version | Historical content, including revised versions with a SeriesInstanceUID still in `index`. Use `crdc_series_uuid` plus `min_idc_version`/`max_idc_version` to pin a revision. For current-release additions use `series_init_idc_version`/`series_revised_idc_version` in `index`; those fields have different semantics. |

Available Tables

SKILL.md carries a compact map of the table families. This is the full inventory with row granularity and contents. Always call client.fetch_index("table_name") before querying any of them — it is safe and idempotent for all tables, including those loaded automatically at startup.

TableRow GranularityDescription
index1 row = 1 DICOM seriesPrimary metadata for all current IDC data
version_metadata_index1 row = 1 IDC release versionIDC version release timestamps; join on idc_version to correlate series with their release date
collections_index1 row = 1 collectionCollection-level metadata and descriptions
analysis_results_index1 row = 1 analysis result collectionMetadata about derived datasets (annotations, segmentations)
clinical_index1 row = 1 (collection, table, column) tripleDictionary mapping clinical data table columns to collections
sm_index1 row = 1 slide microscopy seriesSlide Microscopy (pathology) series metadata
sm_instance_index1 row = 1 slide microscopy instanceInstance-level (SOPInstanceUID) metadata for slide microscopy
seg_index1 row = 1 DICOM Segmentation seriesSegmentation metadata: algorithm, segment count, reference to source image series
ann_index1 row = 1 DICOM ANN seriesMicroscopy Bulk Simple Annotations series metadata; references annotated image series
ann_group_index1 row = 1 annotation groupDetailed annotation group metadata: graphic type, annotation count, property codes, algorithm
contrast_index1 row = 1 series with contrast infoContrast agent metadata: agent name, ingredient, administration route (CT, MR, PT, XA, RF)
volume_geometry_index1 row = 1 CT/MR/PT series3D volume geometry validation for single-frame CT, MR, and PT series; boolean checks for orientation, spacing, dimensions, and slice positions; composite regularly_spaced_3d_volume flag
rtstruct_index1 row = 1 RTSTRUCT seriesRT Structure Set metadata: total ROI count, ROI names, generation algorithms, interpreted types, and the referenced image series UID
ct_index1 row = 1 CT seriesCT acquisition/reconstruction parameters: pixel spacing, slice thickness, kVp, convolution kernel, tube current (min/max for dose-modulated), exposure, spiral pitch, scan options
mr_index1 row = 1 MR seriesMR acquisition/sequence parameters: field strength, scanning sequence, TE (array for multi-echo), TR, flip angle, DiffusionBValue (array for DWI), pixel bandwidth, receive coil, number of temporal positions
pt_index1 row = 1 PET seriesPET acquisition/reconstruction/radiopharmaceutical parameters: series type, units, decay/scatter/attenuation correction, reconstruction method, radionuclide, injected dose, frame duration (array for dynamic PET)
prior_versions_index1 row = 1 historical CRDC series versionHistorical content, including revised versions with a SeriesInstanceUID still in index. Use crdc_series_uuid plus min_idc_version/max_idc_version to pin a revision. For current-release additions use series_init_idc_version/series_revised_idc_version in index; those fields have different semantics.
Raw lines 23 to 49
50## Accessing Index Tables

Accessing Index Tables

Raw lines 50 to 51
52### Via SQL (recommended for filtering/aggregation)
54```python
55from idc_index import IDCClient
56client = IDCClient()
58# Query the primary index (always available)
59results = client.sql_query("SELECT * FROM index WHERE Modality = 'CT' LIMIT 10")
61# Fetch and query additional indices
62client.fetch_index("collections_index")
63collections = client.sql_query("SELECT collection_id, cancer_types, tumor_locations FROM collections_index")
65client.fetch_index("analysis_results_index")
66analysis = client.sql_query("SELECT * FROM analysis_results_index LIMIT 5")
67```

Via SQL (recommended for filtering/aggregation)

from idc_index import IDCClient
client = IDCClient()

# Query the primary index (always available)
results = client.sql_query("SELECT * FROM index WHERE Modality = 'CT' LIMIT 10")

# Fetch and query additional indices
client.fetch_index("collections_index")
collections = client.sql_query("SELECT collection_id, cancer_types, tumor_locations FROM collections_index")

client.fetch_index("analysis_results_index")
analysis = client.sql_query("SELECT * FROM analysis_results_index LIMIT 5")
Raw lines 52 to 68
69### As pandas DataFrames (direct access)
71```python
72# Primary index (always available after client initialization)
73df = client.index
75# Fetch and access on-demand indices
76client.fetch_index("sm_index")
77sm_df = client.sm_index
78```

As pandas DataFrames (direct access)

# Primary index (always available after client initialization)
df = client.index

# Fetch and access on-demand indices
client.fetch_index("sm_index")
sm_df = client.sm_index
Raw lines 69 to 79
80## Discovering Table Schemas
82The `indices_overview` dictionary contains complete schema information for all tables.
83Schema `mode: REPEATED` means a list-valued column; `type: STRING` alone does not imply
84a scalar string. Inspect both fields, or use `DESCRIBE` after fetching the table. **Always consult this when writing queries or exploring data structure.**
86**DICOM attribute mapping:** Many columns are populated directly from DICOM attributes in the source files. The column description in the schema indicates when a column corresponds to a DICOM attribute (e.g., "DICOM Modality attribute" or references a DICOM tag). This allows leveraging DICOM knowledge when querying — standard DICOM attribute names like `PatientID`, `StudyInstanceUID`, `Modality`, `BodyPartExamined` work as expected.
88```python
89from idc_index import IDCClient
90client = IDCClient()
92# List all available indices with descriptions
93for name, info in client.indices_overview.items():
94 print(f"\n{name}:")
95 print(f" Installed: {info['installed']}")
96 print(f" Description: {info['description']}")
98# Get complete schema for a specific index (columns, types, descriptions)
99schema = client.indices_overview["index"]["schema"]
100print(f"\nTable: {schema['table_description']}")
101print("\nColumns:")
102for col in schema['columns']:
103 desc = col.get('description', 'No description')
104 # Description indicates if column is from DICOM attribute
105 print(f" {col['name']} ({col['type']}): {desc}")
107# Find columns that are DICOM attributes (check description for "DICOM" reference)
108dicom_cols = [c['name'] for c in schema['columns'] if 'DICOM' in c.get('description', '').upper()]
109print(f"\nDICOM-sourced columns: {dicom_cols}")
110```
112**Alternative: use `get_index_schema()` method:**
113```python
114schema = client.get_index_schema("index")
115# Returns same schema dict: {'table_description': ..., 'columns': [...]}
116```

Discovering Table Schemas

The indices_overview dictionary contains complete schema information for all tables. Schema mode: REPEATED means a list-valued column; type: STRING alone does not imply a scalar string. Inspect both fields, or use DESCRIBE after fetching the table. Always consult this when writing queries or exploring data structure.

DICOM attribute mapping: Many columns are populated directly from DICOM attributes in the source files. The column description in the schema indicates when a column corresponds to a DICOM attribute (e.g., "DICOM Modality attribute" or references a DICOM tag). This allows leveraging DICOM knowledge when querying — standard DICOM attribute names like PatientID, StudyInstanceUID, Modality, BodyPartExamined work as expected.

from idc_index import IDCClient
client = IDCClient()

# List all available indices with descriptions
for name, info in client.indices_overview.items():
    print(f"\n{name}:")
    print(f"  Installed: {info['installed']}")
    print(f"  Description: {info['description']}")

# Get complete schema for a specific index (columns, types, descriptions)
schema = client.indices_overview["index"]["schema"]
print(f"\nTable: {schema['table_description']}")
print("\nColumns:")
for col in schema['columns']:
    desc = col.get('description', 'No description')
    # Description indicates if column is from DICOM attribute
    print(f"  {col['name']} ({col['type']}): {desc}")

# Find columns that are DICOM attributes (check description for "DICOM" reference)
dicom_cols = [c['name'] for c in schema['columns'] if 'DICOM' in c.get('description', '').upper()]
print(f"\nDICOM-sourced columns: {dicom_cols}")

**Alternative: use get_index_schema() method:**

schema = client.get_index_schema("index")
# Returns same schema dict: {'table_description': ..., 'columns': [...]}
Raw lines 80 to 117
118### Finding which table contains a column
120The most common schema question is "where does `SliceThickness` live?" — the primary `index`
121holds series-level metadata only, so modality-specific acquisition parameters are in dedicated
122tables. Search the overview rather than guessing; neither call fetches anything:
124```python
125# Find which table(s) contain a specific column (no fetch required)
126target = "SliceThickness"
127for table_name, info in client.indices_overview.items():
128 if any(c["name"] == target for c in info["schema"]["columns"]):
129 print(f"'{target}' is in: {table_name}")
130# → 'SliceThickness' is in: ct_index
132# List all columns in a table from the schema (no fetch required)
133ct_cols = [c["name"] for c in client.indices_overview["ct_index"]["schema"]["columns"]]
134print("ct_index columns:", ct_cols)
135# → ['SeriesInstanceUID', 'PixelSpacing_row_mm', 'PixelSpacing_col_mm', 'Rows',
136# 'Columns', 'SliceThickness', 'KVP', 'ConvolutionKernel', ...]
137```
139Then `client.fetch_index("ct_index")` and join to `index` on `SeriesInstanceUID`.

Finding which table contains a column

The most common schema question is "where does SliceThickness live?" — the primary index holds series-level metadata only, so modality-specific acquisition parameters are in dedicated tables. Search the overview rather than guessing; neither call fetches anything:

# Find which table(s) contain a specific column (no fetch required)
target = "SliceThickness"
for table_name, info in client.indices_overview.items():
    if any(c["name"] == target for c in info["schema"]["columns"]):
        print(f"'{target}' is in: {table_name}")
# → 'SliceThickness' is in: ct_index

# List all columns in a table from the schema (no fetch required)
ct_cols = [c["name"] for c in client.indices_overview["ct_index"]["schema"]["columns"]]
print("ct_index columns:", ct_cols)
# → ['SeriesInstanceUID', 'PixelSpacing_row_mm', 'PixelSpacing_col_mm', 'Rows',
#    'Columns', 'SliceThickness', 'KVP', 'ConvolutionKernel', ...]

Then client.fetch_index("ct_index") and join to index on SeriesInstanceUID.

Raw lines 118 to 140
141## Key Columns Reference
143Most common columns in the primary `index` table (use `indices_overview` for complete list and descriptions):
145| Column | Type | DICOM | Description |
146|--------|------|-------|-------------|
147| `collection_id` | STRING | No | IDC collection identifier |
148| `analysis_result_id` | STRING | No | If applicable, indicates what analysis results collection given series is part of |
149| `source_DOI` | STRING | No | DOI linking to dataset details; use for learning more about the content and for attribution (see citations below) |
150| `PatientID` | STRING | Yes | Patient identifier |
151| `StudyInstanceUID` | STRING | Yes | DICOM Study UID |
152| `SeriesInstanceUID` | STRING | Yes | DICOM Series UID — use for downloads/viewing |
153| `Modality` | STRING | Yes | Imaging modality (CT, MR, PT, SM, SEG, ANN, RTSTRUCT, etc.) |
154| `BodyPartExamined` | STRING | Yes | Anatomical region |
155| `SeriesDescription` | STRING | Yes | Description of the series |
156| `Manufacturer` | STRING | Yes | Equipment manufacturer |
157| `StudyDate` | STRING | Yes | Date study was performed |
158| `PatientSex` | STRING | Yes | Patient sex |
159| `PatientAge` | STRING | Yes | Patient age at time of study |
160| `license_short_name` | STRING | No | License type (CC BY 4.0, CC BY-NC 4.0, etc.) |
161| `series_size_MB` | FLOAT | No | Size of series in megabytes |
162| `instanceCount` | INTEGER | No | Number of DICOM instances in series |
163| `SOPClassUID` | STRING | Yes | DICOM SOP Class UID (identifies the object/service class, e.g., CT Image Storage) |
164| `TransferSyntaxUID` | STRING | Yes | DICOM Transfer Syntax UID (encoding/compression method) |
166**DICOM = Yes**: Column value extracted from the DICOM attribute with the same name. Refer to the [DICOM standard](https://dicom.nema.org/medical/dicom/current/output/chtml/part06/chapter_6.html) for numeric tag mappings. Use standard DICOM knowledge for expected values and formats.

Key Columns Reference

Most common columns in the primary index table (use indices_overview for complete list and descriptions):

ColumnTypeDICOMDescription
collection_idSTRINGNoIDC collection identifier
analysis_result_idSTRINGNoIf applicable, indicates what analysis results collection given series is part of
source_DOISTRINGNoDOI linking to dataset details; use for learning more about the content and for attribution (see citations below)
PatientIDSTRINGYesPatient identifier
StudyInstanceUIDSTRINGYesDICOM Study UID
SeriesInstanceUIDSTRINGYesDICOM Series UID — use for downloads/viewing
ModalitySTRINGYesImaging modality (CT, MR, PT, SM, SEG, ANN, RTSTRUCT, etc.)
BodyPartExaminedSTRINGYesAnatomical region
SeriesDescriptionSTRINGYesDescription of the series
ManufacturerSTRINGYesEquipment manufacturer
StudyDateSTRINGYesDate study was performed
PatientSexSTRINGYesPatient sex
PatientAgeSTRINGYesPatient age at time of study
license_short_nameSTRINGNoLicense type (CC BY 4.0, CC BY-NC 4.0, etc.)
series_size_MBFLOATNoSize of series in megabytes
instanceCountINTEGERNoNumber of DICOM instances in series
SOPClassUIDSTRINGYesDICOM SOP Class UID (identifies the object/service class, e.g., CT Image Storage)
TransferSyntaxUIDSTRINGYesDICOM Transfer Syntax UID (encoding/compression method)

DICOM = Yes: Column value extracted from the DICOM attribute with the same name. Refer to the DICOM standard for numeric tag mappings. Use standard DICOM knowledge for expected values and formats.

Raw lines 141 to 167
168## Join Column Reference
170Use this table to identify join columns between index tables. Always call `client.fetch_index("table_name")` before using a table in SQL.
172| Table A | Table B | Join Condition |
173|---------|---------|----------------|
174| `index` | `collections_index` | `index.collection_id = collections_index.collection_id` |
175| `index` | `sm_index` | `index.SeriesInstanceUID = sm_index.SeriesInstanceUID` |
176| `index` | `seg_index` | `index.SeriesInstanceUID = seg_index.segmented_SeriesInstanceUID` |
177| `index` | `ann_index` | `index.SeriesInstanceUID = ann_index.SeriesInstanceUID` |
178| `ann_index` | `ann_group_index` | `ann_index.SeriesInstanceUID = ann_group_index.SeriesInstanceUID` |
179| `index` | `clinical_index` | `index.collection_id = clinical_index.collection_id` (dictionary only; actual clinical rows join by PatientID within the collection) |
180| `index` | `contrast_index` | `index.SeriesInstanceUID = contrast_index.SeriesInstanceUID` |
181| `index` | `volume_geometry_index` | `index.SeriesInstanceUID = volume_geometry_index.SeriesInstanceUID` |
182| `index` | `rtstruct_index` | `index.SeriesInstanceUID = rtstruct_index.SeriesInstanceUID` |
183| `rtstruct_index` | `index` (source images) | `rtstruct_index.referenced_SeriesInstanceUID = index.SeriesInstanceUID` |
184| `index` | `ct_index` | `index.SeriesInstanceUID = ct_index.SeriesInstanceUID` |
185| `index` | `mr_index` | `index.SeriesInstanceUID = mr_index.SeriesInstanceUID` |
186| `index` | `pt_index` | `index.SeriesInstanceUID = pt_index.SeriesInstanceUID` |
188For complete query examples using these joins, see `references/sql_patterns.md`.

Join Column Reference

Use this table to identify join columns between index tables. Always call client.fetch_index("table_name") before using a table in SQL.

Table ATable BJoin Condition
indexcollections_indexindex.collection_id = collections_index.collection_id
indexsm_indexindex.SeriesInstanceUID = sm_index.SeriesInstanceUID
indexseg_indexindex.SeriesInstanceUID = seg_index.segmented_SeriesInstanceUID
indexann_indexindex.SeriesInstanceUID = ann_index.SeriesInstanceUID
ann_indexann_group_indexann_index.SeriesInstanceUID = ann_group_index.SeriesInstanceUID
indexclinical_indexindex.collection_id = clinical_index.collection_id (dictionary only; actual clinical rows join by PatientID within the collection)
indexcontrast_indexindex.SeriesInstanceUID = contrast_index.SeriesInstanceUID
indexvolume_geometry_indexindex.SeriesInstanceUID = volume_geometry_index.SeriesInstanceUID
indexrtstruct_indexindex.SeriesInstanceUID = rtstruct_index.SeriesInstanceUID
rtstruct_indexindex (source images)rtstruct_index.referenced_SeriesInstanceUID = index.SeriesInstanceUID
indexct_indexindex.SeriesInstanceUID = ct_index.SeriesInstanceUID
indexmr_indexindex.SeriesInstanceUID = mr_index.SeriesInstanceUID
indexpt_indexindex.SeriesInstanceUID = pt_index.SeriesInstanceUID

For complete query examples using these joins, see references/sql_patterns.md.

Raw lines 168 to 189
190## Troubleshooting
192**Issue:** Column not found in table
193- **Cause:** Column name misspelled or doesn't exist in that table
194- **Solution:** Use `client.indices_overview["table_name"]["schema"]["columns"]` to list available columns
196**Issue:** DataFrame access returns None
197- **Cause:** Index not fetched or property name incorrect
198- **Solution:** Fetch first with `client.fetch_index()`, then access via property matching the index name

Troubleshooting

Issue: Column not found in table

  • Cause: Column name misspelled or doesn't exist in that table
  • Solution: Use client.indices_overview["table_name"]["schema"]["columns"] to list available columns

Issue: DataFrame access returns None

  • Cause: Index not fetched or property name incorrect
  • Solution: Fetch first with client.fetch_index(), then access via property matching the index name
Raw lines 190 to 199
200## Resources
202- Complete index table documentation: https://idc-index.readthedocs.io/en/latest/indices_reference.html
203- `references/sql_patterns.md` for query examples using these tables
204- `references/clinical_data_guide.md` for clinical data workflows
205- `references/digital_pathology_guide.md` for pathology-specific indices

Resources

  • Complete index table documentation: https://idc-index.readthedocs.io/en/latest/indices_reference.html
  • references/sql_patterns.md for query examples using these tables
  • references/clinical_data_guide.md for clinical data workflows
  • references/digital_pathology_guide.md for pathology-specific indices
Raw lines 200 to 205