Skip to content

Commit 17c5211

Browse files
committed
fixed huggingface upload
1 parent e38a07e commit 17c5211

23 files changed

Lines changed: 2518 additions & 1828 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ data/output/*
213213
!data/input/.gitkeep
214214
!data/interim/.gitkeep
215215
!data/output/.gitkeep
216+
# data/shared is NOT ignored - contains shared cache files
216217

217218
# Log directories
218219
logs/*

BATCH_PROCESSING.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ data/
7171

7272
### 6. **HuggingFace Upload (Optional)**
7373
- Upload after each successful file processing
74-
- Dataset name appended to repo_id for multiple files
75-
- Example: `username/repo-dataset1_name`, `username/repo-dataset2_name`
74+
- All datasets uploaded to the same repository as subfolders
75+
- Each dataset becomes a subfolder: `{dataset_name}/train/` and `{dataset_name}/test/`
76+
- Example: Single repo `username/my-datasets` contains:
77+
- `dataset1_name/train/chunk_*.parquet`
78+
- `dataset1_name/test/chunk_*.parquet`
79+
- `dataset2_name/train/chunk_*.parquet`
80+
- `dataset2_name/test/chunk_*.parquet`
7681

7782
## Usage Examples
7883

@@ -105,16 +110,18 @@ uv run preprocess run-all --batch-mode \
105110

106111
### With HuggingFace Upload
107112
```bash
108-
# Upload each processed dataset
113+
# Upload each processed dataset to a single repository as subfolders
109114
uv run preprocess run-all --batch-mode \
110115
--input-dir data/input \
111116
--repo-id username/my-datasets \
112117
--token $HF_TOKEN
113118

114-
# Results in:
115-
# - username/my-datasets-dataset1
116-
# - username/my-datasets-dataset2
117-
# - ...
119+
# Results in single repository: username/my-datasets
120+
# With subfolders:
121+
# - dataset1_name/train/chunk_*.parquet
122+
# - dataset1_name/test/chunk_*.parquet
123+
# - dataset2_name/train/chunk_*.parquet
124+
# - dataset2_name/test/chunk_*.parquet
118125
```
119126

120127
### Step-by-Step Mode (Legacy, Two-Step Approach)

README.md

Lines changed: 161 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ A preprocessing pipeline that converts h5ad single-cell RNA-seq files into "cell
1212
- **Structured logging** - Eliot logging with detailed diagnostics
1313
- **HGNC gene mapping** - Official gene name conversions (auto-created when needed)
1414
- **Stratified splits** - Train/test splits maintaining age distribution
15+
- **Publication metadata** - Optional CellxGene API lookup for publication info (DOI, title, etc.)
1516
- **Batch processing** - Process multiple h5ad files in one run
1617
- **Auto-detection** - Finds h5ad files in specified input folder
1718

@@ -42,13 +43,13 @@ uv run preprocess download
4243

4344
# Run full pipeline (auto-detects h5ad in data/input/)
4445
# This processes everything in ONE streaming pass: h5ad → cell sentences → age extraction → train/test split → output
45-
uv run preprocess run-all
46+
uv run preprocess run
4647

4748
# Or specify input file explicitly
48-
uv run preprocess run-all path/to/file.h5ad --input-dir ./data/input
49+
uv run preprocess run path/to/file.h5ad --input-dir ./data/input
4950

5051
# Process multiple files in batch mode
51-
uv run preprocess run-all --batch-mode --input-dir ./data/input
52+
uv run preprocess run --batch-mode --input-dir ./data/input
5253
```
5354

5455
### Upload to HuggingFace (Optional)
@@ -63,7 +64,7 @@ cp .env.template .env
6364
Then run with repo ID:
6465

6566
```bash
66-
uv run preprocess run-all --repo-id "username/dataset-name"
67+
uv run preprocess run --repo-id "username/dataset-name"
6768
```
6869

6970
Get your HuggingFace token from: https://huggingface.co/settings/tokens
@@ -78,19 +79,19 @@ uv run pytest tests/ -v
7879
uv run pytest tests/test_integration.py::TestIntegrationPipeline -v -s
7980

8081
# Clean up test directories older than 7 days
81-
uv run cleanup-tests
82+
uv run preprocess cleanup
8283

8384
# Remove all test directories
84-
uv run cleanup-tests --days 0
85+
uv run preprocess cleanup --days 0
8586
```
8687

8788
See `tests/README.md` for more details.
8889

8990
## Usage
9091

91-
### Run All Steps (One-Step Streaming - Recommended)
92+
### Run Pipeline (One-Step Streaming - Recommended)
9293

93-
The `run-all` command uses a **one-step streaming approach** that processes everything in a single pass:
94+
The `run` command uses a **one-step streaming approach** that processes everything in a single pass:
9495
- Reads h5ad chunks
9596
- Creates cell sentences
9697
- Extracts age from development_stage
@@ -100,99 +101,209 @@ The `run-all` command uses a **one-step streaming approach** that processes ever
100101

101102
```bash
102103
# Auto-detect h5ad file from data/input/
103-
uv run preprocess run-all
104+
uv run preprocess run
104105

105106
# Batch mode - process all h5ad files in a directory
106-
uv run preprocess run-all --batch-mode --input-dir ./data/input
107+
uv run preprocess run --batch-mode --input-dir ./data/input
107108

108109
# Or specify file and folders
109-
uv run preprocess run-all /path/to/file.h5ad \
110+
uv run preprocess run /path/to/file.h5ad \
110111
--output-dir ./data/output \
111112
--repo-id "username/dataset-name" # Optional, for upload
112113

113114
# Skip train/test split (produce single parquet dataset)
114115
# Useful when you want HuggingFace users to decide on their own splitting
115-
uv run preprocess run-all /path/to/file.h5ad \
116+
uv run preprocess run /path/to/file.h5ad \
116117
--skip-train-test-split \
117118
--output-dir ./data/output
119+
120+
# Publication metadata lookup is enabled by default
121+
# This adds columns: collection_id, publication_title, publication_doi, publication_contact
122+
# To disable: --no-lookup-publication
123+
uv run preprocess run /path/to/file.h5ad \
124+
--output-dir ./data/output
118125
```
119126

127+
### Command Options
128+
129+
The `run` command supports many options for fine-tuning:
130+
131+
**Input/Output:**
132+
- `h5ad_path` (optional argument) - Path to h5ad file or directory (auto-detects from `--input-dir` if not provided)
133+
- `--input-dir` - Directory containing input files (default: `./data/input`)
134+
- `--output-dir` / `-o` - Directory for final output files (default: `./data/output`)
135+
- `--interim-dir` - Directory for interim files (default: `./data/interim`)
136+
137+
**Processing Options:**
138+
- `--chunk-size` / `-c` - Number of cells per chunk (default: `10000`)
139+
- `--top-genes` - Number of top expressed genes per cell (default: `2000`)
140+
- `--test-size` - Proportion of data for test set (default: `0.05`)
141+
- `--skip-train-test-split` - Skip train/test split and produce single parquet dataset
142+
- `--batch-mode` - Process all h5ad files in input directory
143+
- `--skip-existing` - Skip datasets that already have output files
144+
145+
**Compression:**
146+
- `--compression` - Compression algorithm: `uncompressed`, `snappy`, `gzip`, `lzo`, `brotli`, `lz4`, `zstd` (default: `zstd`)
147+
- `--compression-level` - Compression level: 1-9 for zstd/gzip, 1-11 for brotli (default: `3`)
148+
- `--use-pyarrow` / `--no-pyarrow` - Use pyarrow backend for parquet writes (default: `True`)
149+
150+
**HGNC Gene Mapping:**
151+
- `--mappers` / `-m` - Path to HGNC mappers pickle file (optional, auto-created if needed)
152+
- `--create-hgnc` - Force creation of HGNC mapper (default: auto-created only if needed)
153+
154+
**HuggingFace Upload:**
155+
- `--repo-id` / `-r` - HuggingFace repository ID (e.g., `username/dataset-name`)
156+
- `--token` / `-t` - HuggingFace API token (can also use `HF_TOKEN` env var)
157+
158+
**Publication Metadata:**
159+
- `--lookup-publication` / `--no-lookup-publication` - Enable/disable CellxGene API lookup (default: enabled)
160+
161+
**Logging:**
162+
- `--log-dir` - Directory for log files, separate log per file (default: `./logs`)
163+
164+
**Other:**
165+
- `--keep-interim` - Keep interim parquet files after processing (default: False, cleaned up to save space)
166+
167+
### Publication Metadata Lookup
168+
169+
For datasets from [CellxGene Discover](https://cellxgene.cziscience.com/), publication metadata lookup is **enabled by default**. This automatically adds publication information:
170+
171+
```bash
172+
# Publication lookup is enabled by default
173+
uv run preprocess run ./data/input/10cc50a0-af80-4fa1-b668-893dd5c0113a.h5ad
174+
175+
# To disable publication lookup
176+
uv run preprocess run ./data/input/file.h5ad --no-lookup-publication
177+
178+
# In batch mode (enabled by default)
179+
uv run preprocess run --batch-mode --input-dir ./data/input
180+
```
181+
182+
This queries the CellxGene API and adds the following columns to your output:
183+
- `collection_id` - CellxGene collection ID
184+
- `publication_title` - Title of the associated publication/collection
185+
- `publication_doi` - DOI of the publication (if available)
186+
- `publication_contact` - Contact name for the publication
187+
188+
**Note:** The API lookup may fail for some datasets if:
189+
- The dataset is not from CellxGene Discover
190+
- The CellxGene API changes
191+
- Network issues occur
192+
193+
When lookup fails, processing continues without publication metadata.
194+
120195
### Run Individual Steps (Legacy Two-Step Approach)
121196

122197
If you need more control, you can run individual steps. Note: This creates interim files.
123198

124-
#### Step 1: Create HGNC Mapper
199+
#### Download Dataset
125200

126201
```bash
127-
uv run preprocess step1-hgnc-mapper --interim-dir ./data/interim
202+
# Download with default URL (AIDA dataset)
203+
uv run preprocess download
204+
205+
# Download from custom URL
206+
uv run preprocess download --url https://example.com/dataset.h5ad
207+
208+
# Specify output directory and filename
209+
uv run preprocess download \
210+
--url https://example.com/dataset.h5ad \
211+
--input-dir ./data/input \
212+
--filename custom_name.h5ad
213+
214+
# Force re-download even if file exists
215+
uv run preprocess download --force
128216
```
129217

130-
#### Step 2: Convert H5AD to Parquet (Two-Step Approach)
218+
**Download Command Options:**
219+
- `--url` / `-u` - URL to download dataset from (default: AIDA dataset URL)
220+
- `--input-dir` / `-i` - Directory to save downloaded files (default: `./data/input`)
221+
- `--filename` / `-f` - Optional filename (if not provided, extracted from URL)
222+
- `--force` - Force re-download even if file exists
223+
- `--log-file` / `-l` - Path to eliot log file (optional)
131224

132-
**Note:** The `run-all` command now uses the one-step approach which is more efficient.
133-
Use this only if you need separate steps.
225+
#### Create HGNC Mapper
134226

135227
```bash
136-
# Auto-detect h5ad from input folder
137-
uv run preprocess step2-convert-h5ad --input-dir ./data/input
138-
139-
# Or specify file explicitly
140-
uv run preprocess step2-convert-h5ad /path/to/file.h5ad \
141-
--mappers ./data/interim/hgnc_mappers.pkl \
142-
--interim-dir ./data/interim/parquet_chunks \
143-
--chunk-size 10000 \
144-
--top-genes 2000
228+
# Create HGNC mapper explicitly (usually auto-created when needed)
229+
uv run preprocess hgnc-mapper --interim-dir ./data/interim
230+
231+
# Or force creation during run command
232+
uv run preprocess run --create-hgnc
145233
```
146234

147-
#### Step 3: Create Train/Test Split (Two-Step Approach)
235+
**HGNC Mapper Command Options:**
236+
- `--interim-dir` / `-i` - Directory to save interim files (HGNC mappers) (default: `./data/interim`)
237+
- `--log-file` / `-l` - Path to eliot log file (optional)
148238

149-
This step can be skipped if you want users on HuggingFace to decide on their own splitting strategy. Use `--skip-train-test-split` flag in the `run-all` command.
239+
#### Upload to HuggingFace
150240

151241
```bash
152-
uv run preprocess step3-train-test-split \
153-
--interim-dir ./data/interim/parquet_chunks \
242+
# Upload a single dataset directory (uses default repo-id if not specified)
243+
uv run preprocess upload \
154244
--output-dir ./data/output \
155-
--test-size 0.05 \
156-
--random-state 42
157-
```
245+
--token $HF_TOKEN
158246

159-
#### Step 4: Upload to HuggingFace
247+
# Or specify custom repo-id
248+
uv run preprocess upload \
249+
--output-dir ./data/output \
250+
--repo-id "username/dataset-name" \
251+
--token $HF_TOKEN
160252

161-
```bash
162-
uv run preprocess step4-upload \
253+
# With custom README file
254+
uv run preprocess upload \
163255
--output-dir ./data/output \
256+
--repo-id "username/dataset-name" \
257+
--readme ./README.md \
258+
--token $HF_TOKEN
259+
260+
# Or upload during processing (per-file uploads)
261+
uv run preprocess run /path/to/file.h5ad \
164262
--repo-id "username/dataset-name" \
165263
--token $HF_TOKEN
166264
```
167265

266+
**Upload Command Options:**
267+
- `--output-dir` / `-o` - Directory containing train/test subdirectories (default: `./data/output`)
268+
- `--repo-id` / `-r` - HuggingFace repository ID (default: `longevity-genie/cell2sentence4longevity-data`)
269+
- `--token` / `-t` - HuggingFace API token (required, can also use `HF_TOKEN` env var)
270+
- `--readme` - Path to README file to include in the dataset (optional)
271+
- `--log-file` / `-l` - Path to eliot log file (optional)
272+
168273
## Batch Processing
169274

170275
Process multiple h5ad files efficiently. See `BATCH_PROCESSING.md` for full details.
171276

172277
```bash
173278
# Process all h5ad files in a directory
174-
uv run preprocess run-all --batch-mode --input-dir ./data/input
279+
uv run preprocess run --batch-mode --input-dir ./data/input
175280

176-
# With upload to HuggingFace
177-
uv run preprocess run-all --batch-mode \
281+
# With upload to HuggingFace (uploads after each successful file)
282+
uv run preprocess run --batch-mode \
178283
--input-dir ./data/input \
179284
--repo-id username/my-datasets \
180285
--token $HF_TOKEN
286+
287+
# Skip files that already have output
288+
uv run preprocess run --batch-mode \
289+
--input-dir ./data/input \
290+
--skip-existing
181291
```
182292

183293
Key features:
184294
- **One-step streaming**: No interim files, everything in one pass
185295
- **Memory efficient**: Processes terabytes of data with constant memory usage
186296
- **Error isolation**: Failures in one file don't stop others
187297
- **Per-file logging**: Separate logs for each dataset
298+
- **Batch summary**: Creates `batch_processing_summary.tsv` with timing and status for all files
188299

189300
## Project Structure
190301

191302
```
192303
cell2sentence4longevity/
193304
├── src/cell2sentence4longevity/
194-
│ ├── cli.py # Main CLI
195-
│ ├── preprocess.py # Preprocessing CLI (one-step streaming)
305+
│ ├── preprocess.py # Main CLI with all commands
306+
│ ├── cleanup.py # Cleanup utilities
196307
│ └── preprocessing/
197308
│ ├── hgnc_mapper.py # Gene mapping
198309
│ ├── h5ad_converter.py # H5AD conversion (one-step & two-step)
@@ -210,12 +321,17 @@ cell2sentence4longevity/
210321
All operations use Eliot structured logging. To enable file logging:
211322

212323
```bash
213-
uv run preprocess run-all /path/to/file.h5ad --log-file ./logs/pipeline.log
324+
# Logs are written to --log-dir (default: ./logs)
325+
# Each dataset gets its own log directory
326+
uv run preprocess run /path/to/file.h5ad --log-dir ./logs
327+
328+
# In batch mode, each file gets its own log subdirectory
329+
uv run preprocess run --batch-mode --log-dir ./logs
214330
```
215331

216-
This creates:
217-
- `./logs/pipeline.json` - Machine-readable structured logs
218-
- `./logs/pipeline.log` - Human-readable formatted logs
332+
This creates per-dataset logs:
333+
- `./logs/{dataset_name}/pipeline.json` - Machine-readable structured logs
334+
- `./logs/{dataset_name}/pipeline.log` - Human-readable formatted logs
219335

220336
### Log Analysis
221337

187 KB
Binary file not shown.
3.78 MB
Binary file not shown.

data/shared/hgnc_mappers.parquet

1.68 MB
Binary file not shown.

0 commit comments

Comments
 (0)