Skip to content

HiPCTProject/OCMI_data_management

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

Multimodal Imaging Pipeline — File Structure Guide

Overview

This document describes the directory structure for the HiP-CT / LabCT / Histology / Xenium spatial transcriptomics pipeline, organised around the sample (whole organ) as the root entity. The path to any file encodes its full physical provenance.


Core Principles

Principle Detail
Sample-centric root Each organ is the top-level entity; everything hangs from it
Path = provenance organ → chunks → blocks → cores mirrors the physical cutting chain
Modality at each level HiP-CT, LabCT, Histology, Xenium appear wherever they apply
Registration alongside data Each physical level has its own registration/ folder
Xenium runs at project level Run data + overview image live outside all sample folders
Blocks at two levels Under organ/blocks/ (small samples) OR organ/chunks/chunk/blocks/ (large organs)
Cores are fully equipped Cores support labct, histology, xenium, and registration — same as blocks

Top-Level Project Structure

<project_root>/
│
├── xenium_runs/                          # ALL Xenium run data — outside every sample
│   └── xenium_run_<run_id>/
│       ├── run_overview_image.ome.tif    # whole-slide overview (all ROIs on this slide)
│       ├── run_metadata.json
│       └── roi_<r01>/                   # one folder per sample ROI on the slide
│           ├── raw/
│           ├── processed/
│           ├── he_image/
│           └── metadata/
│
├── organ_<donor_id>_<organ>/            # one folder per sample
└── organ_<donor_id>_<organ>/

Why Xenium runs live at project level

A single Xenium run places multiple samples on one slide. The overview image captures the whole slide and belongs to no single sample. Each block/xenium/ and core/xenium/ folder holds only a JSON reference file pointing to the relevant ROI in xenium_runs/. Registration transforms (Xenium → histology) remain inside the block's or core's own registration/ folder.


Sample Folder Structure

organ_<donor_id>_<organ>/
├── metadata/
│   ├── donor_metadata.json
│   └── organ_processing_metadata.json
├── hipct/
│   ├── whole_organ_scan/
│   │   ├── raw/  ├── processed/  └── metadata/
│   └── zoom_scan_<z01>/
│       ├── raw/  ├── processed/  └── metadata/
├── labct/                                # whole-organ LabCT — small organs only
│   ├── raw/  ├── processed/  └── metadata/
├── blocks/                               # blocks cut DIRECTLY from organ (small samples)
│   └── block_<b01>/  ...
├── chunks/                               # ~5 cm cuts — large organs only
│   └── chunk_<c01>/  ...
└── registration/
    ├── hipct_whole_to_labct_organ/
    └── hipct_organ_to_chunk/

Block Structure

Blocks (~1–2 cm paraffin-embedded) exist at two points in the hierarchy:

  • organ_.../blocks/block_<id>/ — cut directly from the organ (small samples)
  • organ_.../chunks/chunk_<id>/blocks/block_<id>/ — cut from a chunk

The internal structure is identical. The registration anchor differs: small-organ blocks use labct_block_to_hipct_organ/; chunk-level blocks use labct_block_to_hipct_chunk/.

block_<b01>/
├── metadata/
├── labct/
│   ├── raw/  ├── processed/  └── metadata/
├── histology/
│   ├── single_sections/
│   │   └── section_<s01>/
│   │       ├── raw/  ├── processed/  └── metadata/
│   └── serial_sections/
│       ├── metadata/
│       └── section_<s001>/
│           ├── raw/  └── processed/
├── xenium/
│   └── run_ref.json                      # JSON pointer to xenium_runs/…/roi_<r>/
├── cores/
│   └── core_<k01>/  ...                  # see Core Structure below
└── registration/
    ├── labct_block_to_hipct_chunk/        # (or _to_hipct_organ/ for small samples)
    ├── histology_to_labct_block/
    ├── xenium_roi_to_histology/
    └── serial_sections_to_labct_block/

Core Structure

Cores (~1 mm TMA-style) are punched from blocks. They support the same modalities as blocks — including histology (single or serial sections) and Xenium ST if the core is independently sectioned and placed on a Xenium slide.

core_<k01>/
├── labct/
│   ├── raw/  ├── processed/  └── metadata/
├── histology/
│   ├── single_sections/
│   │   └── section_<s01>/
│   │       ├── raw/  ├── processed/  └── metadata/
│   └── serial_sections/
│       ├── metadata/
│       └── section_<s001>/
│           ├── raw/  └── processed/
├── xenium/
│   └── run_ref.json                      # JSON pointer if core was Xenium-profiled
└── registration/
    ├── labct_core_to_labct_block/
    ├── histology_to_labct_core/
    └── xenium_roi_to_histology_core/

Registration Convention

Each physical level has a registration/ folder. Sub-directories are named <source>_to_<target>/ and contain:

transform.h5              # affine or B-spline (ITK HDF5)
deformation_field.nii.gz  # dense deformation field (non-rigid)
reg_metadata.json         # software, metric, date

Transforms chain across levels to achieve full-pipeline registration, e.g.:

histology section
  → histology_to_labct_block
    → labct_block_to_hipct_chunk
      → hipct_chunk_to_hipct_organ

Naming Conventions

Entity Pattern Example
Organ / sample organ_<donor_id>_<organ> organ_D001_adult_heart
Chunk chunk_<organ_id>_<cNN> chunk_D001_adult_heart_c01
Block block_<organ_id>_<bNN> block_D001_adult_heart_b01
Core core_<organ_id>_<kNN> core_D001_adult_heart_k01
HiP-CT zoom zoom_scan_<zNN> zoom_scan_z01
Section section_<sNNN> section_s001
Xenium run xenium_run_<run_id> xenium_run_XR001
Xenium ROI roi_<rNN> roi_r01

Example A — Large Organ: Adult Heart

An adult heart is scanned whole with HiP-CT, then physically cut. One chunk (left ventricular free wall) is scanned with HiP-CT and LabCT. A block is cut from the chunk and processed for serial-section histology and Xenium. A core from the block is also sectioned for histology and profiled independently with Xenium.

project_root/
│
├── xenium_runs/
│   └── xenium_run_XR005/
│       ├── run_overview_image.ome.tif    # adult heart block + fetal heart block on same slide
│       ├── run_metadata.json
│       ├── roi_r01/                      # adult heart block_b01 ROI
│       ├── roi_r02/                      # adult heart core_k01 ROI (core on same slide)
│       └── roi_r03/                      # fetal heart block ROI (different organ, same run)
│
└── organ_D001_adult_heart/
    ├── metadata/
    ├── hipct/
    │   ├── whole_organ_scan/             # full adult heart volume
    │   └── zoom_scan_z01/               # zoom into myocardium
    ├── labct/                            # EMPTY — adult heart too large for whole-organ LabCT
    ├── blocks/                           # EMPTY — adult heart uses chunks; blocks under chunks/
    ├── chunks/
    │   └── chunk_D001_adult_heart_c01/  # left ventricular free wall
    │       ├── metadata/
    │       ├── hipct/
    │       │   ├── whole_chunk_scan/
    │       │   └── zoom_scan_z01/
    │       ├── labct/
    │       ├── blocks/
    │       │   └── block_D001_adult_heart_b01/
    │       │       ├── labct/
    │       │       ├── histology/
    │       │       │   └── serial_sections/     # serial sections for 3-D reconstruction
    │       │       ├── xenium/
    │       │       │   └── run_ref.json         # → xenium_runs/XR005/roi_r01/
    │       │       ├── cores/
    │       │       │   └── core_D001_adult_heart_k01/
    │       │       │       ├── labct/           # high-res core LabCT
    │       │       │       ├── histology/       # sections from the core
    │       │       │       ├── xenium/
    │       │       │       │   └── run_ref.json # → xenium_runs/XR005/roi_r02/
    │       │       │       └── registration/
    │       │       │           ├── labct_core_to_labct_block/
    │       │       │           ├── histology_to_labct_core/
    │       │       │           └── xenium_roi_to_histology_core/
    │       │       └── registration/
    │       │           ├── labct_block_to_hipct_chunk/
    │       │           ├── histology_to_labct_block/
    │       │           └── xenium_roi_to_histology/
    │       └── registration/
    │           ├── hipct_chunk_to_labct_chunk/
    │           └── hipct_chunk_to_hipct_organ/
    └── registration/
        ├── hipct_whole_to_labct_organ/
        └── hipct_organ_to_chunk/

Example B — Small Sample: Fetal Heart

A fetal heart is small enough to scan whole with both HiP-CT and LabCT. No chunking step is needed. Two blocks are cut directly from the intact organ. One block is processed for Xenium (sharing the same run slide as the adult heart block above). A core from that block is independently sectioned for histology but not Xenium-profiled.

project_root/
│
├── xenium_runs/
│   └── xenium_run_XR005/
│       └── roi_r03/                      # fetal heart block ROI on shared slide
│
└── organ_F001_fetal_heart/
    ├── metadata/
    ├── hipct/
    │   └── whole_organ_scan/             # whole fetal heart HiP-CT
    ├── labct/
    │   ├── raw/                          # POPULATED — fetal heart scanned whole
    │   ├── processed/
    │   └── metadata/
    ├── blocks/                           # POPULATED — blocks cut directly from organ
    │   ├── block_F001_fetal_heart_b01/
    │   │   ├── labct/
    │   │   ├── histology/
    │   │   │   └── single_sections/
    │   │   ├── xenium/
    │   │   │   └── run_ref.json          # → xenium_runs/XR005/roi_r03/
    │   │   ├── cores/
    │   │   │   └── core_F001_fetal_heart_k01/
    │   │   │       ├── labct/
    │   │   │       ├── histology/        # core sectioned independently
    │   │   │       ├── xenium/           # run_ref.json left blank (no Xenium for this core)
    │   │   │       └── registration/
    │   │   │           ├── labct_core_to_labct_block/
    │   │   │           └── histology_to_labct_core/
    │   │   └── registration/
    │   │       ├── labct_block_to_hipct_organ/   # note: _organ not _chunk
    │   │       ├── histology_to_labct_block/
    │   │       └── xenium_roi_to_histology/
    │   └── block_F001_fetal_heart_b02/   # second block — histology only, no Xenium
    │       ├── histology/
    │       └── registration/
    ├── chunks/                           # EMPTY — no chunking for fetal heart
    └── registration/
        └── hipct_whole_to_labct_organ/

Xenium Reference File Format

{
  "_comment": "Edit run_id and roi_id with actual Xenium run values.",
  "run_id": "xenium_run_XR005",
  "roi_id": "roi_r01",
  "project_xenium_runs_path": "../../../../../../xenium_runs/"
}

Using the Setup Script

Create a single new sample

python create_pipeline_structure.py \
    --root /path/to/project \
    --sample organ_D001_adult_heart

Scaffold all existing sample folders

python create_pipeline_structure.py \
    --root /path/to/project \
    --populate-existing

Preview without writing anything

python create_pipeline_structure.py \
    --root /path/to/project \
    --sample organ_F001_fetal_heart \
    --dry-run
Flag Description
--root <path> Project root directory (required)
--sample <name> Create structure for a single named sample
--populate-existing Scaffold all existing top-level folders under --root
--dry-run Print what would be created; do not write to disk
--quiet Suppress per-folder output

Quick Reference

Data type Location
Whole-organ HiP-CT organ_.../hipct/whole_organ_scan/
HiP-CT zoom organ_.../hipct/zoom_scan_<z>/
Whole-organ LabCT (small organs) organ_.../labct/
Chunk HiP-CT organ_.../chunks/chunk_<c>/hipct/
Chunk LabCT organ_.../chunks/chunk_<c>/labct/
Block LabCT .../blocks/block_<b>/labct/
Block histology .../blocks/block_<b>/histology/
Core LabCT .../blocks/block_<b>/cores/core_<k>/labct/
Core histology .../blocks/block_<b>/cores/core_<k>/histology/
Core Xenium .../blocks/block_<b>/cores/core_<k>/xenium/run_ref.json
Xenium ROI data xenium_runs/xenium_run_<r>/roi_<roi>/
Xenium overview image xenium_runs/xenium_run_<r>/run_overview_image.ome.tif
Registration transforms registration/ at each physical level

About

a repo for making and organising file tree structures for OCMI

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages