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

use_cases.md

273 lines · skills/imaging-data-commons/references/use_cases.md at 5f2bc03

Open on GitHub

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

1# Common Use Cases for IDC
2
3**Tested with:** idc-index 0.12.5 (IDC data version v24)
4
5These download and local-file processing examples are illustrative; metadata queries were
6smoke-tested with the pinned IDC release. This guide provides end-to-end workflow examples for common IDC use cases. Each use case demonstrates the full workflow from query to download with best practices.
7

Common Use Cases for IDC

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

These download and local-file processing examples are illustrative; metadata queries were smoke-tested with the pinned IDC release. This guide provides end-to-end workflow examples for common IDC use cases. Each use case demonstrates the full workflow from query to download with best practices.

Raw lines 1 to 7
8## When to Use This Guide
9
10Load this guide when you need:
11- Complete end-to-end workflow examples for training dataset creation
12- Patterns for multi-step data selection and download workflows
13- Examples of license-aware data handling for commercial use
14- Visualization workflows for data preview before download
16For core API patterns (query, download, visualize, citations), see the "Core Capabilities" section in the main SKILL.md.

When to Use This Guide

Load this guide when you need:

  • Complete end-to-end workflow examples for training dataset creation
  • Patterns for multi-step data selection and download workflows
  • Examples of license-aware data handling for commercial use
  • Visualization workflows for data preview before download

For core API patterns (query, download, visualize, citations), see the "Core Capabilities" section in the main SKILL.md.

Raw lines 8 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## Use Case 1: Find and Download Lung CT Scans for Deep Learning
25**Objective:** Build training dataset of lung CT scans from NLST collection
27**Steps:**
28```python
29from idc_index import IDCClient
31client = IDCClient()
33# 1. Query for lung CT scans with specific criteria
34query = """
35SELECT
36 PatientID,
37 SeriesInstanceUID,
38 SeriesDescription,
39 crdc_series_uuid, series_aws_url, license_short_name, source_DOI
40FROM index
41WHERE collection_id = 'nlst'
42 AND Modality = 'CT'
43 AND BodyPartExamined = 'CHEST'
44 AND license_short_name = 'CC BY 4.0'
45ORDER BY PatientID
46LIMIT 100
47"""
49results = client.sql_query(query)
50print(f"Found {len(results)} series from {results['PatientID'].nunique()} patients")
52# 2. Download data organized by patient
53client.download_from_selection(
54 seriesInstanceUID=list(results['SeriesInstanceUID'].values),
55 downloadDir="./training_data",
56 dirTemplate="%collection_id/%PatientID/%SeriesInstanceUID"
59# 3. Save manifest for reproducibility
60results.to_csv('training_manifest.csv', index=False)
61```

Use Case 1: Find and Download Lung CT Scans for Deep Learning

Objective: Build training dataset of lung CT scans from NLST collection

Steps:

from idc_index import IDCClient

client = IDCClient()

# 1. Query for lung CT scans with specific criteria
query = """
SELECT
  PatientID,
  SeriesInstanceUID,
  SeriesDescription,
  crdc_series_uuid, series_aws_url, license_short_name, source_DOI
FROM index
WHERE collection_id = 'nlst'
  AND Modality = 'CT'
  AND BodyPartExamined = 'CHEST'
  AND license_short_name = 'CC BY 4.0'
ORDER BY PatientID
LIMIT 100
"""

results = client.sql_query(query)
print(f"Found {len(results)} series from {results['PatientID'].nunique()} patients")

# 2. Download data organized by patient
client.download_from_selection(
    seriesInstanceUID=list(results['SeriesInstanceUID'].values),
    downloadDir="./training_data",
    dirTemplate="%collection_id/%PatientID/%SeriesInstanceUID"
)

# 3. Save manifest for reproducibility
results.to_csv('training_manifest.csv', index=False)
Raw lines 23 to 62
63## Use Case 2: Query Brain MRI by Manufacturer for Quality Study
65**Objective:** Compare image quality across different MRI scanner manufacturers
67**Steps:**
68```python
69from idc_index import IDCClient
70import pandas as pd
72client = IDCClient()
74# Query for brain MRI grouped by manufacturer
75query = """
76SELECT
77 Manufacturer,
78 ManufacturerModelName,
79 COUNT(DISTINCT SeriesInstanceUID) as num_series,
80 COUNT(DISTINCT PatientID) as num_patients
81FROM index
82WHERE Modality = 'MR'
83 AND BodyPartExamined LIKE '%BRAIN%'
84GROUP BY Manufacturer, ManufacturerModelName
85HAVING num_series >= 10
86ORDER BY num_series DESC
87"""
89manufacturers = client.sql_query(query)
90print(manufacturers)
92# Download sample from each manufacturer for comparison
93for _, row in manufacturers.head(3).iterrows():
94 mfr = row['Manufacturer']
95 model = row['ManufacturerModelName']
97 # Use DataFrame equality to handle quotes and missing values in vendor strings.
98 series = client.index[
99 client.index['Manufacturer'].eq(mfr) &
100 client.index['ManufacturerModelName'].eq(model) &
101 client.index['Modality'].eq('MR') &
102 client.index['BodyPartExamined'].str.contains('BRAIN', na=False)
103 ].head(5)
104 client.download_from_selection(
105 seriesInstanceUID=list(series['SeriesInstanceUID'].values),
106 downloadDir=f"./quality_study/{mfr.replace(' ', '_')}"
107 )
108```

Use Case 2: Query Brain MRI by Manufacturer for Quality Study

Objective: Compare image quality across different MRI scanner manufacturers

Steps:

from idc_index import IDCClient
import pandas as pd

client = IDCClient()

# Query for brain MRI grouped by manufacturer
query = """
SELECT
  Manufacturer,
  ManufacturerModelName,
  COUNT(DISTINCT SeriesInstanceUID) as num_series,
  COUNT(DISTINCT PatientID) as num_patients
FROM index
WHERE Modality = 'MR'
  AND BodyPartExamined LIKE '%BRAIN%'
GROUP BY Manufacturer, ManufacturerModelName
HAVING num_series >= 10
ORDER BY num_series DESC
"""

manufacturers = client.sql_query(query)
print(manufacturers)

# Download sample from each manufacturer for comparison
for _, row in manufacturers.head(3).iterrows():
    mfr = row['Manufacturer']
    model = row['ManufacturerModelName']

    # Use DataFrame equality to handle quotes and missing values in vendor strings.
    series = client.index[
        client.index['Manufacturer'].eq(mfr) &
        client.index['ManufacturerModelName'].eq(model) &
        client.index['Modality'].eq('MR') &
        client.index['BodyPartExamined'].str.contains('BRAIN', na=False)
    ].head(5)
    client.download_from_selection(
        seriesInstanceUID=list(series['SeriesInstanceUID'].values),
        downloadDir=f"./quality_study/{mfr.replace(' ', '_')}"
    )
Raw lines 63 to 109
110## Use Case 3: Visualize Series Without Downloading
112**Objective:** Preview imaging data before committing to download
114```python
115from idc_index import IDCClient
116import webbrowser
118client = IDCClient()
120series_list = client.sql_query("""
121 SELECT SeriesInstanceUID, PatientID, SeriesDescription
122 FROM index
123 WHERE collection_id = 'acrin_nsclc_fdg_pet' AND Modality = 'PT'
124 LIMIT 10
125""")
127# Preview each in browser
128for _, row in series_list.iterrows():
129 viewer_url = client.get_viewer_URL(seriesInstanceUID=row['SeriesInstanceUID'])
130 print(f"Patient {row['PatientID']}: {row['SeriesDescription']}")
131 print(f" View at: {viewer_url}")
132 # webbrowser.open(viewer_url) # Uncomment to open automatically
133```
135For additional visualization options, see the [IDC Portal getting started guide](https://learn.canceridc.dev/portal/getting-started) or [SlicerIDCBrowser](https://github.com/ImagingDataCommons/SlicerIDCBrowser) for 3D Slicer integration.

Use Case 3: Visualize Series Without Downloading

Objective: Preview imaging data before committing to download

from idc_index import IDCClient
import webbrowser

client = IDCClient()

series_list = client.sql_query("""
    SELECT SeriesInstanceUID, PatientID, SeriesDescription
    FROM index
    WHERE collection_id = 'acrin_nsclc_fdg_pet' AND Modality = 'PT'
    LIMIT 10
""")

# Preview each in browser
for _, row in series_list.iterrows():
    viewer_url = client.get_viewer_URL(seriesInstanceUID=row['SeriesInstanceUID'])
    print(f"Patient {row['PatientID']}: {row['SeriesDescription']}")
    print(f"  View at: {viewer_url}")
    # webbrowser.open(viewer_url)  # Uncomment to open automatically

For additional visualization options, see the IDC Portal getting started guide or SlicerIDCBrowser for 3D Slicer integration.

Raw lines 110 to 136
137## Use Case 4: License-Aware Batch Download for Commercial Use
139**Objective:** Download only CC-BY licensed data suitable for commercial applications
141**Steps:**
142```python
143from idc_index import IDCClient
145client = IDCClient()
147# Query ONLY for CC BY licensed data (allows commercial use with attribution)
148query = """
149SELECT
150 SeriesInstanceUID,
151 collection_id,
152 PatientID,
153 Modality,
154 crdc_series_uuid, series_aws_url, license_short_name, source_DOI
155FROM index
156WHERE license_short_name IN ('CC BY 3.0', 'CC BY 4.0')
157 AND Modality IN ('CT', 'MR')
158 AND BodyPartExamined IN ('CHEST', 'BRAIN', 'ABDOMEN')
159LIMIT 200
160"""
162cc_by_data = client.sql_query(query)
164print(f"Found {len(cc_by_data)} CC BY licensed series")
165print(f"Collections: {cc_by_data['collection_id'].unique()}")
167# Download with license verification
168client.download_from_selection(
169 seriesInstanceUID=list(cc_by_data['SeriesInstanceUID'].values),
170 downloadDir="./commercial_dataset",
171 dirTemplate="%collection_id/%Modality/%PatientID/%SeriesInstanceUID"
174# Save license information
175cc_by_data.to_csv('commercial_dataset_manifest_CC-BY_ONLY.csv', index=False)
176```

Use Case 4: License-Aware Batch Download for Commercial Use

Objective: Download only CC-BY licensed data suitable for commercial applications

Steps:

from idc_index import IDCClient

client = IDCClient()

# Query ONLY for CC BY licensed data (allows commercial use with attribution)
query = """
SELECT
  SeriesInstanceUID,
  collection_id,
  PatientID,
  Modality,
  crdc_series_uuid, series_aws_url, license_short_name, source_DOI
FROM index
WHERE license_short_name IN ('CC BY 3.0', 'CC BY 4.0')
  AND Modality IN ('CT', 'MR')
  AND BodyPartExamined IN ('CHEST', 'BRAIN', 'ABDOMEN')
LIMIT 200
"""

cc_by_data = client.sql_query(query)

print(f"Found {len(cc_by_data)} CC BY licensed series")
print(f"Collections: {cc_by_data['collection_id'].unique()}")

# Download with license verification
client.download_from_selection(
    seriesInstanceUID=list(cc_by_data['SeriesInstanceUID'].values),
    downloadDir="./commercial_dataset",
    dirTemplate="%collection_id/%Modality/%PatientID/%SeriesInstanceUID"
)

# Save license information
cc_by_data.to_csv('commercial_dataset_manifest_CC-BY_ONLY.csv', index=False)
Raw lines 137 to 177
178## Use Case 5: Batch Download with Filtering
180**Objective:** Download a large filtered dataset in batches to avoid timeouts
182**Steps:**
183```python
184from idc_index import IDCClient
185import pandas as pd
187client = IDCClient()
189# Find chest CT scans from GE scanners with a permissive license
190query = """
191SELECT
192 SeriesInstanceUID,
193 PatientID,
194 collection_id,
195 ManufacturerModelName
196FROM index
197WHERE Modality = 'CT'
198 AND BodyPartExamined = 'CHEST'
199 AND Manufacturer = 'GE MEDICAL SYSTEMS'
200 AND license_short_name = 'CC BY 4.0'
201LIMIT 100
202"""
204results = client.sql_query(query)
206# Save manifest for reproducibility
207results.to_csv('lung_ct_manifest.csv', index=False)
209# Download in batches to avoid timeout
210batch_size = 10
211for i in range(0, len(results), batch_size):
212 batch = results.iloc[i:i+batch_size]
213 client.download_from_selection(
214 seriesInstanceUID=list(batch['SeriesInstanceUID'].values),
215 downloadDir=f"./data/batch_{i//batch_size}"
216 )
217```

Use Case 5: Batch Download with Filtering

Objective: Download a large filtered dataset in batches to avoid timeouts

Steps:

from idc_index import IDCClient
import pandas as pd

client = IDCClient()

# Find chest CT scans from GE scanners with a permissive license
query = """
SELECT
  SeriesInstanceUID,
  PatientID,
  collection_id,
  ManufacturerModelName
FROM index
WHERE Modality = 'CT'
  AND BodyPartExamined = 'CHEST'
  AND Manufacturer = 'GE MEDICAL SYSTEMS'
  AND license_short_name = 'CC BY 4.0'
LIMIT 100
"""

results = client.sql_query(query)

# Save manifest for reproducibility
results.to_csv('lung_ct_manifest.csv', index=False)

# Download in batches to avoid timeout
batch_size = 10
for i in range(0, len(results), batch_size):
    batch = results.iloc[i:i+batch_size]
    client.download_from_selection(
        seriesInstanceUID=list(batch['SeriesInstanceUID'].values),
        downloadDir=f"./data/batch_{i//batch_size}"
    )
Raw lines 178 to 218
219## Use Case 6: Integration with Analysis Pipelines
221**Objective:** Load downloaded DICOM files into Python for processing
223**Read individual DICOM files with pydicom:**
224```python
225import pydicom
226import os
228series_dir = "./data/rider/rider_pilot/RIDER-1007893286/CT_1.3.6.1..."
230dicom_files = [os.path.join(series_dir, f) for f in os.listdir(series_dir)
231 if f.endswith('.dcm')]
233ds = pydicom.dcmread(dicom_files[0])
234print(f"Patient ID: {ds.PatientID}")
235print(f"Modality: {ds.Modality}")
236print(f"Image shape: {ds.pixel_array.shape}")
237```
239**Load one conventional CT series with SimpleITK:**
241This example requires local DICOM files and is illustrative. Use `volume_geometry_index`
242to screen candidates, then check orientation, spacing, missing/duplicate slices, and pixel
243units in the actual files. Sorting only `ImagePositionPatient[2]` is wrong for oblique or
244sagittal series, and raw `pixel_array` values are not automatically Hounsfield units.
246```python
247import SimpleITK as sitk
249series_path = "./data/ct_series"
250series_ids = sitk.ImageSeriesReader.GetGDCMSeriesIDs(series_path)
251if len(series_ids) != 1:
252 raise ValueError(f"Select exactly one CT series; found {len(series_ids)}")
253reader = sitk.ImageSeriesReader()
254dicom_names = reader.GetGDCMSeriesFileNames(series_path, series_ids[0])
255reader.SetFileNames(dicom_names)
256image = reader.Execute()
257print(image.GetSize(), image.GetSpacing(), image.GetDirection())
258# Confirm CT rescale/unit semantics before treating intensities as HU.
259image = sitk.Cast(image, sitk.sitkFloat32)
260smoothed = sitk.CurvatureFlow(image1=image, timeStep=0.125, numberOfIterations=5)
261sitk.WriteImage(smoothed, "processed_volume.nii.gz")
262```
264For ML datasets, split by patient (and where needed institution), keep all studies and
265series from one patient in the same split, and document collection/label provenance.
266Selecting 100 series is not equivalent to selecting 100 independent patients.

Use Case 6: Integration with Analysis Pipelines

Objective: Load downloaded DICOM files into Python for processing

Read individual DICOM files with pydicom:

import pydicom
import os

series_dir = "./data/rider/rider_pilot/RIDER-1007893286/CT_1.3.6.1..."

dicom_files = [os.path.join(series_dir, f) for f in os.listdir(series_dir)
               if f.endswith('.dcm')]

ds = pydicom.dcmread(dicom_files[0])
print(f"Patient ID: {ds.PatientID}")
print(f"Modality: {ds.Modality}")
print(f"Image shape: {ds.pixel_array.shape}")

Load one conventional CT series with SimpleITK:

This example requires local DICOM files and is illustrative. Use volume_geometry_index to screen candidates, then check orientation, spacing, missing/duplicate slices, and pixel units in the actual files. Sorting only ImagePositionPatient[2] is wrong for oblique or sagittal series, and raw pixel_array values are not automatically Hounsfield units.

import SimpleITK as sitk

series_path = "./data/ct_series"
series_ids = sitk.ImageSeriesReader.GetGDCMSeriesIDs(series_path)
if len(series_ids) != 1:
    raise ValueError(f"Select exactly one CT series; found {len(series_ids)}")
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(series_path, series_ids[0])
reader.SetFileNames(dicom_names)
image = reader.Execute()
print(image.GetSize(), image.GetSpacing(), image.GetDirection())
# Confirm CT rescale/unit semantics before treating intensities as HU.
image = sitk.Cast(image, sitk.sitkFloat32)
smoothed = sitk.CurvatureFlow(image1=image, timeStep=0.125, numberOfIterations=5)
sitk.WriteImage(smoothed, "processed_volume.nii.gz")

For ML datasets, split by patient (and where needed institution), keep all studies and series from one patient in the same split, and document collection/label provenance. Selecting 100 series is not equivalent to selecting 100 independent patients.

Raw lines 219 to 267
268## Resources
270- Main SKILL.md for core API patterns (query, download, visualize)
271- `references/clinical_data_guide.md` for clinical data integration workflows
272- `references/sql_patterns.md` for additional SQL query patterns
273- `references/index_tables_guide.md` for complex join patterns

Resources

  • Main SKILL.md for core API patterns (query, download, visualize)
  • references/clinical_data_guide.md for clinical data integration workflows
  • references/sql_patterns.md for additional SQL query patterns
  • references/index_tables_guide.md for complex join patterns
Raw lines 268 to 273