Skip to content

Commit e38a07e

Browse files
committed
updated gene resolution
1 parent a2b0bd7 commit e38a07e

16 files changed

Lines changed: 1451 additions & 886 deletions

File tree

.github/workflows/tests.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.13"]
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v5
22+
with:
23+
version: "latest"
24+
25+
- name: Set up Python ${{ matrix.python-version }}
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: ${{ matrix.python-version }}
29+
30+
- name: Cache uv dependencies
31+
uses: actions/cache@v4
32+
with:
33+
path: ~/.cache/uv
34+
key: ${{ runner.os }}-uv-${{ hashFiles('**/uv.lock') }}
35+
restore-keys: |
36+
${{ runner.os }}-uv-
37+
38+
- name: Install dependencies
39+
run: uv sync --dev
40+
41+
- name: Run tests
42+
run: uv run pytest
43+

BATCH_PROCESSING.md

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
The CLI now supports batch processing of multiple h5ad files with memory-efficient processing, per-file logging, error handling, and automatic cleanup of interim files.
5+
The CLI now supports batch processing of multiple h5ad files with **one-step streaming conversion**, memory-efficient processing, per-file logging, and error handling.
66

77
## Key Features
88

@@ -12,11 +12,17 @@ The CLI now supports batch processing of multiple h5ad files with memory-efficie
1212
- Failures in one file don't stop processing of others
1313
- Progress tracking and summary reporting
1414

15-
### 2. **Memory Management** (Critical for Terabytes of Data)
16-
- **Automatic garbage collection** after each processing step
17-
- **Interim file cleanup** (disabled with `--keep-interim` flag)
18-
- Cleans up parquet chunks after creating train/test splits
19-
- Cleans up partial files on errors
15+
### 2. **One-Step Streaming Conversion** (NEW!)
16+
- **No interim files created** - everything happens in a single streaming pass
17+
- Reads h5ad → creates cell sentences → extracts age → splits train/test → writes output
18+
- Memory efficient: data flows through pipeline without intermediate storage
19+
- Significantly faster than two-step approach
20+
21+
### 3. **Memory Management** (Critical for Terabytes of Data)
22+
- **Automatic garbage collection** after each file
23+
- **No interim files** to clean up (one-step approach)
24+
- **Chunked processing**: Never loads entire datasets into memory
25+
- **Backed h5ad loading**: Uses AnnData's backed mode
2026
- Memory is freed between processing different h5ad files
2127

2228
### 3. **Dataset Name Sanitization**
@@ -34,21 +40,16 @@ Example:
3440
```
3541

3642
### 4. **Per-File Directory Structure**
43+
44+
**One-Step Approach (Current):**
3745
```
3846
data/
39-
├── interim/
40-
│ └── parquet_chunks/
41-
│ ├── dataset1_name/
42-
│ │ └── chunks/
43-
│ │ ├── chunk_0000.parquet
44-
│ │ └── ...
45-
│ └── dataset2_name/
46-
│ └── chunks/
47-
│ └── ...
4847
├── output/
4948
│ ├── dataset1_name/
5049
│ │ ├── train/
5150
│ │ │ └── chunks/
51+
│ │ │ ├── chunk_0000.parquet
52+
│ │ │ └── ...
5253
│ │ └── test/
5354
│ │ └── chunks/
5455
│ └── dataset2_name/
@@ -60,6 +61,8 @@ data/
6061
└── pipeline.log
6162
```
6263

64+
**Note:** No interim files are created with the one-step approach!
65+
6366
### 5. **Per-File Logging**
6467
- Each dataset gets its own log directory
6568
- JSON and rendered log files
@@ -93,16 +96,11 @@ uv run preprocess run-all --batch-mode --input-dir data/input
9396
# Or provide directory as argument
9497
uv run preprocess run-all data/input --batch-mode
9598

96-
# With memory-efficient cleanup (default)
99+
# With custom output directory
97100
uv run preprocess run-all --batch-mode \
98101
--input-dir data/input \
99102
--output-dir data/output \
100103
--log-dir logs
101-
102-
# Keep interim files (for debugging)
103-
uv run preprocess run-all --batch-mode \
104-
--input-dir data/input \
105-
--keep-interim
106104
```
107105

108106
### With HuggingFace Upload
@@ -119,25 +117,27 @@ uv run preprocess run-all --batch-mode \
119117
# - ...
120118
```
121119

122-
### Step-by-Step with Batch Mode
120+
### Step-by-Step Mode (Legacy, Two-Step Approach)
121+
122+
If you need to run individual steps separately:
123+
123124
```bash
124-
# Step 2: Convert all h5ad files
125+
# Step 2: Convert all h5ad files to interim parquet (creates interim files)
125126
uv run preprocess step2-convert-h5ad --batch-mode
126127

127-
# Step 3: Add age to all datasets
128-
uv run preprocess step3-add-age --batch-mode
129-
130-
# Step 4: Create splits for all
131-
# (requires manual iteration currently)
128+
# Step 3: Create train/test splits from interim files
129+
uv run preprocess step3-train-test-split --interim-dir data/interim/parquet_chunks
132130
```
133131

132+
**Note:** The `run-all` command now uses the one-step approach, which is faster and more memory efficient.
133+
134134
## Command-Line Options
135135

136136
### New Options
137137

138138
- `--batch-mode`: Enable batch processing of all h5ad files in input directory
139-
- `--keep-interim`: Keep interim parquet files after processing (default: False, cleanup to save space)
140139
- `--log-dir PATH`: Directory for log files (default: `./logs`)
140+
- `--skip-train-test-split`: Skip train/test splitting (writes all data to single directory)
141141

142142
### Existing Options
143143

@@ -154,18 +154,18 @@ uv run preprocess step3-add-age --batch-mode
154154

155155
For processing terabytes of data, the implementation ensures:
156156

157-
1. **Lazy loading**: Polars `scan_parquet` for streaming operations
158-
2. **Chunked processing**: Never loads entire datasets into memory
159-
3. **Forced garbage collection**: `gc.collect()` after each step
160-
4. **Interim cleanup**: Removes large intermediate files after use
157+
1. **One-step streaming**: No interim files created, data flows from h5ad → output directly
158+
2. **Backed h5ad loading**: AnnData backed mode prevents loading entire file into memory
159+
3. **Chunked processing**: Processes data in configurable chunks (default: 10,000 cells)
160+
4. **Forced garbage collection**: `gc.collect()` after each file
161161
5. **File isolation**: Each file processed independently, memory freed between files
162162

163163
## Error Handling
164164

165165
- Per-file try-catch blocks
166166
- Failures logged but don't stop batch processing
167-
- Partial interim files cleaned up on errors (unless `--keep-interim`)
168167
- Summary report shows success/failure for each file
168+
- Memory freed even on errors via forced garbage collection
169169

170170
## Example Output
171171

@@ -180,22 +180,11 @@ PROCESSING FILE 1/3: my_dataset
180180
================================================================================
181181
182182
================================================================================
183-
STEP 2: Converting my_dataset to parquet
183+
PROCESSING: my_dataset
184+
Converting h5ad, extracting age, and creating train/test split in one pass
184185
================================================================================
185-
✓ Step 2 complete for my_dataset
186-
187-
================================================================================
188-
STEP 3: Adding age and cleaning up my_dataset
189-
================================================================================
190-
✓ Step 3 complete for my_dataset
191-
192-
================================================================================
193-
STEP 4: Creating train/test split for my_dataset
194-
================================================================================
195-
✓ Step 4 complete for my_dataset
196-
197-
Cleaning up interim files for my_dataset...
198-
✓ Interim files cleaned up
186+
Processing chunks: 100%|███████████████████| 150/150 [00:15:32<00:00, 6.21s/it]
187+
✓ Conversion complete for my_dataset
199188
200189
================================================================================
201190
PROCESSING FILE 2/3: another_dataset
@@ -228,3 +217,4 @@ All existing functionality is preserved:
228217
- All individual step commands (step1, step2, etc.) still work
229218
- Backward compatible with existing scripts and workflows
230219

220+

0 commit comments

Comments
 (0)