Illumina v1 Sample Sheet Example
This example demonstrates how to parse an Illumina v1 sample sheet using elsheeto and extract key information including header metadata and sample details.
Sample Sheet Format
Illumina v1 sample sheets are organized into sections:
[Header]: Experiment metadata and configuration
[Reads]: Read length specifications
[Settings]: Runtime settings (optional)
[Data]: Sample information with indexing details
Example Script
Here’s the complete example script (examples/read_illumina_v1.py):
1#!/usr/bin/env python3
2"""Example: Reading an Illumina v1 sample sheet.
3
4This example demonstrates how to parse an Illumina v1 sample sheet and extract
5key information including header metadata and sample details.
6
7Usage:
8 python examples/read_illumina_v1.py
9 # or with uv:
10 uv run python examples/read_illumina_v1.py
11"""
12
13from pathlib import Path
14
15from elsheeto import parse_illumina_v1
16
17
18def main():
19 """Parse Illumina v1 sample sheet and display key information."""
20 # Path to the example Illumina v1 sample sheet
21 sample_sheet_path = Path(__file__).parent / "illumina_v1_example1.csv"
22
23 # Get relative path from current working directory for display
24 try:
25 relative_path = sample_sheet_path.relative_to(Path.cwd())
26 except ValueError:
27 # Fallback to absolute path if relative path can't be computed
28 relative_path = sample_sheet_path
29
30 print(f"Reading Illumina v1 sample sheet: {relative_path}")
31 print("=" * 60)
32
33 # Parse the sample sheet using elsheeto's facade function
34 try:
35 sample_sheet = parse_illumina_v1(sample_sheet_path)
36 except Exception as e:
37 print(f"Error parsing sample sheet: {e}")
38 return
39
40 # Extract and display header information
41 header = sample_sheet.header
42 print("HEADER INFORMATION:")
43 print("-" * 30)
44
45 # Display date
46 if header.date:
47 print(f"Date: {header.date}")
48 else:
49 print("Date: Not specified")
50
51 # Display experiment description
52 if header.experiment_name:
53 print(f"Experiment Name: {header.experiment_name}")
54 else:
55 print("Experiment Name: Not specified")
56
57 if header.description:
58 print(f"Description: {header.description}")
59 else:
60 print("Description: Not specified")
61
62 # Display additional header fields
63 print(f"Workflow: {header.workflow}")
64 if header.application:
65 print(f"Application: {header.application}")
66 if header.instrument_type:
67 print(f"Instrument Type: {header.instrument_type}")
68 if header.assay:
69 print(f"Assay: {header.assay}")
70
71 print()
72
73 # Display reads information
74 if sample_sheet.reads:
75 print("READS INFORMATION:")
76 print("-" * 30)
77 print(f"Read lengths: {sample_sheet.reads.read_lengths}")
78 print()
79
80 # Display sample information
81 print("SAMPLE INFORMATION:")
82 print("-" * 30)
83 print(f"Total samples: {len(sample_sheet.data)}")
84 print()
85
86 # Display sample names and IDs
87 print("Sample Details:")
88 for i, sample in enumerate(sample_sheet.data, 1):
89 sample_name = sample.sample_name or "(No name)"
90 print(f" {i:2d}. Sample ID: {sample.sample_id}")
91 print(f" Sample Name: {sample_name}")
92 if sample.sample_project:
93 print(f" Project: {sample.sample_project}")
94 if sample.description:
95 print(f" Description: {sample.description}")
96 if sample.index:
97 print(f" Index: {sample.index}")
98 if sample.index2:
99 print(f" Index2: {sample.index2}")
100 print()
101
102 # Display index information summary
103 print("INDEX SUMMARY:")
104 print("-" * 30)
105 indexed_samples = [s for s in sample_sheet.data if s.index]
106 dual_indexed_samples = [s for s in sample_sheet.data if s.index and s.index2]
107
108 print(f"Samples with index: {len(indexed_samples)}")
109 print(f"Samples with dual indexing: {len(dual_indexed_samples)}")
110
111 if indexed_samples:
112 print("Index adapters used:")
113 unique_i7_ids = {s.i7_index_id for s in indexed_samples if s.i7_index_id}
114 unique_i5_ids = {s.i5_index_id for s in indexed_samples if s.i5_index_id}
115 if unique_i7_ids:
116 print(f" I7 Index IDs: {', '.join(sorted(unique_i7_ids))}")
117 if unique_i5_ids:
118 print(f" I5 Index IDs: {', '.join(sorted(unique_i5_ids))}")
119
120
121if __name__ == "__main__":
122 main()
Key Features Demonstrated
Import and Parsing
The script uses the simple facade function:
from elsheeto import parse_illumina_v1
sample_sheet = parse_illumina_v1(sample_sheet_path)
This single function call handles the entire three-stage parsing process.
Header Information Access
The parsed header provides access to experiment metadata:
header = sample_sheet.header
print(f"Date: {header.date}")
print(f"Experiment Name: {header.experiment_name}")
print(f"Description: {header.description}")
Sample Data Processing
Individual samples can be accessed and processed:
for sample in sample_sheet.data:
print(f"Sample ID: {sample.sample_id}")
print(f"Index: {sample.index}")
print(f"Index2: {sample.index2}")
Index Analysis
The script demonstrates how to analyze indexing patterns:
indexed_samples = [s for s in sample_sheet.data if s.index]
dual_indexed_samples = [s for s in sample_sheet.data if s.index and s.index2]
Sample Data File
The example uses illumina_v1_example1.csv:
1[Header],,,,,,,,,,
2IEMFileVersion,5,,,,,,,,,
3Experiment Name,MyExperimentName,,,,,,,,,
4Date,11.11.2011,,,,,,,,,
5Workflow,GenerateFASTQ,,,,,,,,,
6Application,NextSeq FASTQ Only,,,,,,,,,
7Instrument Type,NovaSeq/MiSeq,,,,,,,,,
8Assay,TruSeq DNA Exome Enrichment,,,,,,,,,
9Index Adapters,TruSeq DNA CD Indexes (96 Indexes),,,,,,,,,
10Description,The Description,,,,,,,,,
11Chemistry,Amplicon,,,,,,,,,
12,,,,,,,,,,
13[Reads],,,,,,,,,,
14149,,,,,,,,,,
15149,,,,,,,,,,
16,,,,,,,,,,
17[Settings],,,,,,,,,,
18,,,,,,,,,,
19[Data],,,,,,,,,,
20Sample_ID,Sample_Name,Sample_Plate,Sample_Well,Index_Plate_Well,I7_Index_ID,index,I5_Index_ID,index2,Sample_Project,Description
21L11-00001_01,,,,A11,AD81,ATCACTCACA,AD81,TTACGGTAAC,,NGS_Seq1_20111111_01
22L11-00002_01,,,,B11,AD82,CGGAGGTAGA,AD82,TTCAGATGGA,,NGS_Seq1_20111111_01
23L11-00003_01,,,,C11,AD83,GAGTTGACAA,AD83,TAGCATCTGT,,NGS_Seq1_20111111_01
24L11-00004_01,,,,D11,AD84,GCCGAACTTG,AD84,GGACGAGATC,,NGS_Seq1_20111111_01
Expected Output
When you run the example script, you should see output like this:
Reading Illumina v1 sample sheet: examples/illumina_v1_example1.csv
============================================================
HEADER INFORMATION:
------------------------------
Date: 11.11.2011
Experiment Name: MyExperimentName
Description: The Description
Workflow: GenerateFASTQ
Application: NextSeq FASTQ Only
Instrument Type: NovaSeq/MiSeq
Assay: TruSeq DNA Exome Enrichment
READS INFORMATION:
------------------------------
Read lengths: [149, 149]
SAMPLE INFORMATION:
------------------------------
Total samples: 4
Sample Details:
1. Sample ID: L11-00001_01
Sample Name: (No name)
Description: NGS_Seq1_20111111_01
Index: ATCACTCACA
Index2: TTACGGTAAC
2. Sample ID: L11-00002_01
Sample Name: (No name)
Description: NGS_Seq1_20111111_01
Index: CGGAGGTAGA
Index2: TTCAGATGGA
3. Sample ID: L11-00003_01
Sample Name: (No name)
Description: NGS_Seq1_20111111_01
Index: GAGTTGACAA
Index2: TAGCATCTGT
4. Sample ID: L11-00004_01
Sample Name: (No name)
Description: NGS_Seq1_20111111_01
Index: GCCGAACTTG
Index2: GGACGAGATC
INDEX SUMMARY:
------------------------------
Samples with index: 4
Samples with dual indexing: 4
Index adapters used:
I7 Index IDs: AD81, AD82, AD83, AD84
I5 Index IDs: AD81, AD82, AD83, AD84
Key Output Sections
Header Information: Date, experiment name, description, and technical details
Sample Information: Complete list of all samples with their metadata
Index Summary: Statistics about indexing patterns used in the experiment
The output shows:
4 dual-indexed samples with both I7 and I5 indices
Index adapter IDs AD81-AD84 for systematic indexing
Complete sample metadata including projects and descriptions
Error Handling
The script includes proper error handling:
try:
sample_sheet = parse_illumina_v1(sample_sheet_path)
except Exception as e:
print(f"Error parsing sample sheet: {e}")
return
This ensures graceful handling of malformed files or parsing issues.
Running the Example
You can run this example in several ways:
# Using uv (recommended)
uv run python examples/read_illumina_v1.py
# Or generate output file
make examples
# Direct execution (if elsheeto is installed)
python examples/read_illumina_v1.py
The example demonstrates elsheeto’s type-safe parsing and shows how easy it is to extract meaningful information from Illumina sample sheets.