Getting Started with xnatR

You have neuroimaging data sitting in an XNAT archive and you need to get it into R — browse what’s available, find specific sessions, and download scans to disk. xnatR gives you a tidy, pipe-friendly interface to the XNAT REST API so you can do all of that without leaving your R session.

Connect and explore in 30 seconds

library(xnatR)

client <- xnat_connect(
  base_url = "https://central.xnat.org",
  username = "myuser",
  password = "mypass",
  use_jsession = TRUE
)

list_projects(client = client)
#> ── XNAT Projects ──────────────────────────────
#> 42 projects
#> # A tibble: 42 × 3
#>    ID              name                    description
#>    <chr>           <chr>                   <chr>
#>  1 CENTRAL_OASIS   Central OASIS Project   Cross-sectional MRI…
#>  2 ABIDE           ABIDE                   Autism Brain Imaging…
#>    …

That’s the pattern: connect once, then use list_* functions to navigate the data hierarchy. Every function accepts an optional client argument; if you omit it, xnatR falls back to a global session set up with authenticate_xnat().

The XNAT data hierarchy

XNAT organises imaging data in a tree:

Project
└── Subject
    └── Experiment (imaging session)
        └── Scan (e.g., T1, BOLD, DWI)
            └── Resource (DICOM, NIFTI, …)
                └── Files

Each level has a corresponding list_*() function that returns a tibble. You drill down by passing IDs from the level above.

How do I find my project?

If you know the project ID, skip ahead. Otherwise, search by keyword:

search_projects("OASIS", client = client)
#> ── XNAT Projects ──────────────────────────────
#> 2 projects
#> # A tibble: 2 × 3
#>   ID              name                  description
#>   <chr>           <chr>                 <chr>
#> 1 CENTRAL_OASIS   Central OASIS Project Cross-sectional MRI…
#> 2 OASIS3          OASIS-3               Longitudinal MRI…

Who is in the project?

subjects <- list_subjects("CENTRAL_OASIS", client = client)
subjects
#> ── XNAT Subjects ──────────────────────────────
#> Project: "CENTRAL_OASIS"
#> 416 subjects
#> # A tibble: 416 × 4
#>   ID         label    project         gender
#>   <chr>      <chr>    <chr>           <chr>
#> 1 OAS1_0001  OAS1_0001 CENTRAL_OASIS  F
#> 2 OAS1_0002  OAS1_0002 CENTRAL_OASIS  M
#>   …

For large projects, use limit and offset for pagination:

first_50 <- list_subjects("CENTRAL_OASIS", limit = 50, client = client)
next_50  <- list_subjects("CENTRAL_OASIS", limit = 50, offset = 50, client = client)

What sessions exist?

list_experiments() returns sessions for a project. Pass subject_id to scope to a single subject, or omit it to get everything:

# All sessions in the project
all_sessions <- list_experiments("CENTRAL_OASIS", client = client)

# Sessions for one subject
subj_sessions <- list_experiments(
  "CENTRAL_OASIS",
  subject_id = "OAS1_0001",
  client = client
)
subj_sessions
#> ── XNAT Experiments ───────────────────────────
#> Project: "CENTRAL_OASIS"
#> Subject: "OAS1_0001"
#> 2 experiments
#> # A tibble: 2 × 4
#>   ID          label        xsiType              date
#>   <chr>       <chr>        <chr>                 <chr>
#> 1 E00001      MR1          xnat:mrSessionData    2005-09-02
#> 2 E00002      MR2          xnat:mrSessionData    2006-11-18

Want the most recent sessions? list_recent_sessions() sorts by date and lets you cap the count:

recent <- list_recent_sessions("CENTRAL_OASIS", n = 5, client = client)
recent

What scans are in a session?

scans <- list_scans(
  project_id    = "CENTRAL_OASIS",
  subject_id    = "OAS1_0001",
  experiment_id = "E00001",
  client        = client
)
scans
#> ── XNAT Scans ─────────────────────────────────
#> 4 scans
#> # A tibble: 4 × 4
#>   ID    type        quality   frames
#>   <chr> <chr>       <chr>     <chr>
#> 1 1     T1          usable    176
#> 2 2     T2          usable    176
#> 3 3     BOLD        usable    132
#> 4 4     DWI         usable    72

How do I download data?

Download all scans from a session

download_files(
  project_id    = "CENTRAL_OASIS",
  subject_id    = "OAS1_0001",
  experiment_id = "E00001",
  dest_dir      = "~/Downloads",
  client        = client
)
#> ℹ Downloading to CENTRAL_OASIS_OAS1_0001_E00001_ALL_ALL.zip
#> ✔ Downloaded to ~/Downloads/CENTRAL_OASIS_OAS1_0001_E00001_ALL_ALL.zip

Download specific scans or resource types

# Just the T1 and BOLD scans
download_files(
  project_id    = "CENTRAL_OASIS",
  subject_id    = "OAS1_0001",
  experiment_id = "E00001",
  scan_id       = c("1", "3"),
  dest_dir      = "~/Downloads",
  client        = client
)

# Only NIFTI resources
download_files(
  project_id    = "CENTRAL_OASIS",
  subject_id    = "OAS1_0001",
  experiment_id = "E00001",
  resource      = "NIFTI",
  dest_dir      = "~/Downloads",
  client        = client
)

Download an entire subject

download_subject() grabs every session for a subject:

download_subject(
  project_id = "CENTRAL_OASIS",
  subject_id = "OAS1_0001",
  dest_dir   = "~/Downloads",
  client     = client
)
#> ℹ Downloading 2 experiments for subject "OAS1_0001"
#> ✔ Downloaded all data for subject "OAS1_0001"

Download a session by experiment ID alone

If you already have the experiment ID (e.g., from a search), you don’t need the full project/subject/experiment triple:

download_experiment(
  experiment_id = "E00001",
  format        = "zip",
  dest_dir      = "~/Downloads",
  extract       = TRUE,
  client        = client
)

Credential management

The examples above used xnat_connect() with explicit credentials. For real work, you’ll want to keep passwords out of your scripts.

Environment variables (best for CI and shared scripts):

# In your .Renviron file:
# XNATR_HOST=https://central.xnat.org
# XNATR_USER=myuser
# XNATR_PASS=mypass

# Then just:
client <- xnat_connect()

Config file (best for interactive use on your own machine):

initialize_config()
# Creates ~/.xnatR_config.yml — edit it with your credentials, then:
client <- xnat_connect()

.netrc file (if you already use one for curl/wget):

machine central.xnat.org login myuser password mypass
client <- xnat_connect(base_url = "https://central.xnat.org")

For servers with self-signed SSL certificates, pass ssl_verify = FALSE.

Clean up

Always log out when you’re done, especially with JSESSION connections:

xnat_logout(invalidate_session = TRUE, client = client)

Next steps

  • vignette("workflows") — common task recipes: batch downloads, finding recent sessions, searching by scan parameters
  • ?xnat_search_builder — the fluent search API for complex queries
  • ?xnat_token_issue — alias tokens for temporary or shared access