merge_session#

qx_utilities.general.sessions.merge_session(studyfolder: str, source: str, target: str, overwrite: str = 'no', raw_data: str = 'copy', original_sessions: str = 'leave', _log=None) bool#

merge_session  --studyfolder=<path> --source=<sessions> --target=<session> [--overwrite=<mode>] [--raw_data=<mode>] [--original_sessions=<action>]

Join multiple sessions into a single session.

Description:

Merges data from multiple source sessions into a target session, handling sequence renumbering, BOLD/BOLDREF indexing, and grouping tags. This is useful when data for a subject is split across multiple scanning sessions and needs to be combined for processing and analysis.

Parameters

--source (str):

A comma-separated list of session IDs or paths to join. Each can be: - A session ID (e.g., 'session1') - assumes <studyfolder>/sessions/<id> - A relative path (e.g., 'other/session1') - relative to studyfolder - An absolute path (e.g., '/data/study/sessions/session1') The sessions will be merged in the order specified, with sequence numbers and indices adjusted accordingly.

--target (str):

The target session ID or path. Can be specified as: - A session ID (e.g., 'merged_session') - creates in <studyfolder>/sessions/ - A relative path (e.g., 'sessions/merged') - relative to studyfolder - An absolute path (e.g., '/data/study/sessions/merged')

--studyfolder (str):

Path to the study folder. This is used as the base for resolving relative paths and for locating sessions when only session IDs are provided (assumes sessions are in <studyfolder>/sessions/).

--overwrite (str, default 'no'):

How to handle existing target folder. Options are 'no' (raise an error if target exists with content), 'clean' (remove existing content and replace with merged data), or 'merge' (add new data to existing session, continuing sequence numbering from where target left off).

--raw_data (str, default 'copy'):

How to handle raw data (dicom/ and bids/ folders). Options are: - 'copy': Copy raw data from source to target (default) - 'move': Move raw data from source to target - 'leave': Do not transfer raw data, only merge session metadata

--original_sessions (str, default 'leave'):

How to handle original source sessions after merging. Options are: - 'leave': Leave original sessions unchanged (default) - 'remove': Remove original sessions after successful merge - 'move:<path>': Move original sessions to specified path (e.g., 'move:/data/backup_sessions'). If a session already exists at the destination, behavior depends on the --overwrite parameter: 'no' skips the move with a warning, while 'clean' or 'merge' replaces the existing session.

Output files

The function creates or modifies a target session folder with the following structure:

<target session id>/
    dicom/              # DICOM files organized by sequence folders
        <seq_num>/      # Sequence folders with renumbered identifiers
    nii/                # NIfTI files with renumbered names
        <seq_num>.nii.gz
        <seq_num>.json
    bids/               # BIDS data (if present in sources)
        <source_session_id>/  # Nested by source session
    session.txt         # Combined session metadata
    session_hcp.txt     # Combined HCP session metadata

Notes

Sequence Renumbering:

When joining sessions, sequence numbers are renumbered to avoid conflicts:

  1. Find maximum sequence number across all source sessions

  2. Determine base increment (1000, 10000, 100000, etc. - next power of 10)

  3. Add base * session_index to each sequence from each source session

Example: If sources have sequences numbered 1010-2010 and 1010-3010, and the maximum is 3010, the base increment will be 10000. The first source's sequences become 11010-12010, the second source's become 21010-23010.

This renumbering is applied to:

  • DICOM subfolder names in the dicom/ folder

  • NIfTI file names in the nii/ folder (both .nii.gz and .json files)

  • Sequence numbers in session.txt and session_hcp.txt files

BOLD/BOLDREF Indexing:

In session_hcp.txt, each bold and boldref sequence is numbered (e.g., bold1, bold2, boldref1, boldref2). When joining sessions, numbers continue from where target left off. Example: target has bold1-bold2, first source adds bold3-bold4, second source adds bold5-bold6.

Grouping Tags:

The se(N) and fm(N) tags group related sequences (same scanning session or fieldmap group). When joining, groups are maintained within each source session and numbers are renumbered to avoid overlap between sessions. Example: If both sources have se(1) and se(2), the first source keeps se(1) and se(2), the second source becomes se(3) and se(4).

BIDS Handling:

If source sessions contain a bids/ folder instead of (or in addition to) dicom/, the BIDS data is preserved by nesting it under the source session ID in the target's bids/ folder.

Derivatives Handling:

The function handles existing derivatives (images/ and hcp/ folders) as follows:

  • If source sessions contain derivatives: Warns user that derivatives will NOT be merged and remain in source folders

  • If overwrite='merge' and target contains derivatives: Raises error to prevent unsafe merge

  • If overwrite='clean': Warns user before removing all content including derivatives

Pre-joined Session Detection:

The function detects if a target session already contains joined sessions by checking for sequence numbers that are 10x+ higher than typical (5+ digits) and multiple sequences sharing the same prefix (e.g., 11010, 11020 share prefix 11, while 21010, 21020 share prefix 21). When detected, only source sequence numbers are adjusted; existing target sequences remain unchanged.

Session and Subject IDs:

The target session ID is used to derive the subject ID. If session ID contains underscore (e.g., 'A_B'), subject ID is the part before the first underscore ('A'). Otherwise, subject and session IDs are the same. Paths in session.txt and session_hcp.txt are updated to be valid within the new target session folder.

Use:

This function only merges raw imaging data (DICOM, NIfTI, BIDS) and session metadata files. Processed derivatives must be regenerated by running the appropriate processing pipelines on the merged session.

Examples

merge_session(
    source='session1,session2,session3',
    target='merged_session',
    studyfolder='/data/my_study',
    overwrite='clean'
)
merge_session(
    source='A_001,A_002',
    target='sessions/A_combined',
    studyfolder='/data/my_study',
    overwrite='merge',
    original_sessions='remove'
)
merge_session(
    source='/data/study/sessions/s1,other_sessions/s2',
    target='/data/study/sessions/merged',
    studyfolder='/data/study',
    overwrite='clean',
    original_sessions='move:archive/merged_sessions'
)