A computational pipeline for designing CRISPR guides targeting homeologous genes in polyploid organisms.
CROPSR identifies high-quality guide RNAs that target multiple homeologs simultaneously while minimizing off-target effects. The pipeline uses ortholog identification, sequence analysis, and scoring algorithms to prioritize guides for multiplex gene editing.
- Python 3.x
- DIAMOND BLAST
- MongoDB (running on
mongodb://127.0.0.1:27017) - GFF database file (
braker.gff.db) - Reference protein sequences
Start with the protein sequence from an Arabidopsis thaliana ortholog.
Example:
>AT_OST1
MDRPAVSGPMDLPIMHDSDRYELVKDIGSGNFGVARLMRDKQSNELVAVKYIERGEKIDENVKREIINHRSLRHPNIVRFKEVILTPTHLAIVMEYASGGELFERICNAGRFSEDEARFFFQQLISGVSYCHAMQVCHRDLKLENTLLDGSPAPRLKICDFGYSKSSVLHSQPKSTVGTPAYIAPEVLLKKEYDGKVADVWSCGVTLYVMLVGAYPFEDPEEPKNFRKTIHRILNVQYAIPDYVHISPECRHLISRIFVADPAKRISIPEIRNHEWFLKNLPADLMNDNTMTTQFDESDQPGQSIEEIMQIIAEATVPPAGTQNLNHYLTGSLDIDDDMEEDLESDLDDLDIDSSGEIVYAM
Run DIAMOND BLAST to identify likely orthologs in the target organism's protein database.
Command:
diamond blastp -d A -q OST1_prot.fa -o OST1_vs_A.tsv \
--very-sensitive --evalue 1e-5 --max-target-seqs 1000 \
--query-cover 30 --subject-cover 30 \
--outfmt 6 qseqid sseqid pident length evalue bitscore qcovhsp scovhsp \
--threads 16Expected Output:
AT_OST1 g3201.t1 89.6 364 3.16e-237 648 100 99.7
AT_OST1 g23419.t1 89.3 364 4.29e-235 643 100 99.7
AT_OST1 g37842.t1 86.0 364 2.47e-220 605 100 99.7
AT_OST1 g36701.t2 81.1 366 5.33e-213 587 100 99.7
Use two_gene_guides.py to identify guides that target two homeologs simultaneously.
Command:
python3 two_gene_guides.py OST1 g3201.t1 g23419.t1Available Options:
| Option | Default | Description |
|---|---|---|
gene_name |
(required) | Name of the target gene |
gene_id_1 |
(required) | First gene/transcript ID (e.g., g15664 or g15664.t2) |
gene_id_2 |
(required) | Second gene/transcript ID (e.g., g36136 or g36136.t1) |
--gffdb |
braker.gff.db |
Path to GFF database file |
--gff |
None |
Path to GFF file (optional) |
--mongo-uri |
mongodb://127.0.0.1:27017 |
MongoDB connection URI |
--db |
CROPSR |
MongoDB database name |
--guides-col |
guides |
Collection name for guides |
--counts-col |
guide_counts |
Collection name for guide counts |
--pam |
NGG |
PAM sequence for Cas9 |
--score-min |
0.10 |
Minimum on-target score threshold |
--write-bed |
False |
Write output in BED format |
--out |
None |
Custom output file path |
- Select the 2 guides with the highest on-target scores
- Manually validate using BLAST or SnapGene to confirm specificity
- Document validated guides in the appropriate validation file
After validation, order the guide oligos from IDT for Golden Gate cloning.
The pipeline generates several output files:
{GENE}_common_keys_with_counts.csv- Guides with occurrence counts{GENE}_common_keys.csv- List of common guide sequences{GENE}_occ2_loci_debug.csv- Debug information for guides with 2 occurrences{GENE}_target1_guides_raw.csv- Raw guides for target 1{GENE}_target2_guides_raw.csv- Raw guides for target 2{GENE}_validated_guides.csv- Final validated guide set
Example gene targets included in this repository:
- TMM (Too Many Mouths)
- SDD1 (Stomatal Density and Distribution 1)
- BLUS1 (Blue Light Signaling 1)
- GAD4 (Glutamate Decarboxylase 4)
- MPK9 (Mitogen-Activated Protein Kinase 9)
- EPF1 (Epidermal Patterning Factor 1)
Each gene folder contains the complete set of input files, intermediate results, and validated guides.
For questions or issues, please open an issue on GitHub.
Sample Output:
Click to expand sample output
================================================================================
STEP 1: Resolve Gene/Transcript IDs
================================================================================
[GFF] Loading database: braker.gff.db
[Target 1] transcript:g3201.t1
Gene: g3201 (Chr11_RagTag:74519010-74523234 -)
Transcripts: g3201.t1
[Target 2] transcript:g23419.t1
Gene: g23419 (Chr1_RagTag:7156515-7160934 -)
Transcripts: g23419.t1
================================================================================
STEP 2: Extract CDS Intervals
================================================================================
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr11_RagTag -> chr11
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[ChromNorm] Chr1_RagTag -> chr1
[Target 1] 9 CDS intervals
[Target 2] 9 CDS intervals
================================================================================
STEP 3: Query Guides from MongoDB
================================================================================
[MongoDB] Connected to CROPSR.guides and CROPSR.guide_counts
[Target 1] Found 63 guides in CDS
[Target 2] Found 66 guides in CDS
[CSV] Wrote 63 rows to OST1_target1_guides_raw.csv
[CSV] Preview (first 2 rows):
{'_id': ObjectId('68c9926fa2ac8ac671809a42'), 'sequence': 'GACCTTGATATTGATAGCAG', 'chromosome': 'chr11', 'start_pos': 74519035, 'end_pos': 74519055, 'cutsite': 74519038, 'PAM_sequence': 'CGG', 'strand': '-', 'on_site_score': 0.3333319556814113}
{'_id': ObjectId('68c9923aa2ac8ac67125912f'), 'sequence': 'CTCCGCTGCTATCAATATCA', 'chromosome': 'chr11', 'start_pos': 74519030, 'end_pos': 74519050, 'cutsite': 74519047, 'PAM_sequence': 'AGG', 'strand': '+', 'on_site_score': 0.11248173285482777}
[CSV] Wrote 66 rows to OST1_target2_guides_raw.csv
[CSV] Preview (first 2 rows):
{'_id': ObjectId('68c99183a2ac8ac671e5098d'), 'sequence': 'GACCTTGATATTGATAGCAG', 'chromosome': 'chr1', 'start_pos': 7156540, 'end_pos': 7156560, 'cutsite': 7156543, 'PAM_sequence': 'CGG', 'strand': '-', 'on_site_score': 0.3333319556814113}
{'_id': ObjectId('68c99152a2ac8ac6718dfc38'), 'sequence': 'CTCCGCTGCTATCAATATCA', 'chromosome': 'chr1', 'start_pos': 7156535, 'end_pos': 7156555, 'cutsite': 7156552, 'PAM_sequence': 'AGG', 'strand': '+', 'on_site_score': 0.11248173285482777}
================================================================================
STEP 4: Identify Common Guides
================================================================================
[Common] 37 guides target both genes
[CSV] Wrote 37 rows to OST1_common_keys.csv
[CSV] Preview (first 5 rows):
{'sequence': 'AAATCACAAATCTTTAGCCT', 'PAM_sequence': 'TGG'}
{'sequence': 'AAATTTTCGCAAGACAATAC', 'PAM_sequence': 'AGG'}
{'sequence': 'AAGGTAATGATTAAGGCTGT', 'PAM_sequence': 'TGG'}
{'sequence': 'AATCATGCAGATAATAACTG', 'PAM_sequence': 'AGG'}
{'sequence': 'AGATTGATGAAAATGTAAAG', 'PAM_sequence': 'AGG'}
================================================================================
STEP 5: Filter by Occurrence Count
================================================================================
[Filtered] 35 guides have exactly 2 occurrences
[CSV] Wrote 37 rows to OST1_common_keys_with_counts.csv
[CSV] Preview (first 5 rows):
{'sequence': 'AAATCACAAATCTTTAGCCT', 'PAM_sequence': 'TGG', 'occurrence_count': 3}
{'sequence': 'AAATTTTCGCAAGACAATAC', 'PAM_sequence': 'AGG', 'occurrence_count': 2}
{'sequence': 'AAGGTAATGATTAAGGCTGT', 'PAM_sequence': 'TGG', 'occurrence_count': 2}
{'sequence': 'AATCATGCAGATAATAACTG', 'PAM_sequence': 'AGG', 'occurrence_count': 2}
{'sequence': 'AGATTGATGAAAATGTAAAG', 'PAM_sequence': 'AGG', 'occurrence_count': 2}
================================================================================
STEP 6: Validate Loci Mapping
================================================================================
[Validated] 35 guides pass all filters
[CSV] Wrote 70 rows to OST1_occ2_loci_debug.csv
[CSV] Preview (first 5 rows):
{'sequence': 'AAATTTTCGCAAGACAATAC', 'PAM_sequence': 'AGG', 'chromosome': 'chr1', 'cutsite': 7157413, 'strand': '-', 'on_site_score': 0.1395602425677323}
{'sequence': 'AAATTTTCGCAAGACAATAC', 'PAM_sequence': 'AGG', 'chromosome': 'chr11', 'cutsite': 74519880, 'strand': '-', 'on_site_score': 0.1395602425677323}
{'sequence': 'AAGGTAATGATTAAGGCTGT', 'PAM_sequence': 'TGG', 'chromosome': 'chr1', 'cutsite': 7156631, 'strand': '+', 'on_site_score': 0.1308576704344441}
{'sequence': 'AAGGTAATGATTAAGGCTGT', 'PAM_sequence': 'TGG', 'chromosome': 'chr11', 'cutsite': 74519126, 'strand': '+', 'on_site_score': 0.1308576704344441}
{'sequence': 'AATCATGCAGATAATAACTG', 'PAM_sequence': 'AGG', 'chromosome': 'chr1', 'cutsite': 7156664, 'strand': '-', 'on_site_score': 0.18188528187536224}
================================================================================
STEP 7: Write Final Results
================================================================================
[CSV] Wrote 35 rows to OST1_validated_guides.csv
[CSV] Preview (first 10 rows):
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'AAATTTTCGCAAGACAATAC', 'PAM_sequence': 'AGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519880, 'g1_strand': '-', 'g1_on_site_score': 0.1395602425677323, 'g2_chr': 'chr1', 'g2_cutsite': 7157413, 'g2_strand': '-', 'g2_on_site_score': 0.1395602425677323}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'AAGGTAATGATTAAGGCTGT', 'PAM_sequence': 'TGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519126, 'g1_strand': '+', 'g1_on_site_score': 0.1308576704344441, 'g2_chr': 'chr1', 'g2_cutsite': 7156631, 'g2_strand': '+', 'g2_on_site_score': 0.1308576704344441}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'AATCATGCAGATAATAACTG', 'PAM_sequence': 'AGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519159, 'g1_strand': '-', 'g1_on_site_score': 0.18188528187536224, 'g2_chr': 'chr1', 'g2_cutsite': 7156664, 'g2_strand': '-', 'g2_on_site_score': 0.18188528187536224}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'AGATTGATGAAAATGTAAAG', 'PAM_sequence': 'AGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74522403, 'g1_strand': '-', 'g1_on_site_score': 0.510388157411842, 'g2_chr': 'chr1', 'g2_cutsite': 7160091, 'g2_strand': '-', 'g2_on_site_score': 0.510388157411842}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'AGCCTTAATCATTACCTTAC', 'PAM_sequence': 'TGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519110, 'g1_strand': '-', 'g1_on_site_score': 0.17795101645534164, 'g2_chr': 'chr1', 'g2_cutsite': 7156615, 'g2_strand': '-', 'g2_on_site_score': 0.17795101645534164}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'AGGCTGTTGGTCCCAGCAGC', 'PAM_sequence': 'AGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519139, 'g1_strand': '+', 'g1_on_site_score': 0.13429787061233003, 'g2_chr': 'chr1', 'g2_cutsite': 7156644, 'g2_strand': '+', 'g2_on_site_score': 0.13429787061233003}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'ATACCTCATCCTCGCTGAAA', 'PAM_sequence': 'CGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74522156, 'g1_strand': '+', 'g1_on_site_score': 0.19684923615862226, 'g2_chr': 'chr1', 'g2_cutsite': 7159836, 'g2_strand': '+', 'g2_on_site_score': 0.19684923615862226}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'CAATGTCCAAGCTACCAGTA', 'PAM_sequence': 'AGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519107, 'g1_strand': '+', 'g1_on_site_score': 0.6352101442820706, 'g2_chr': 'chr1', 'g2_cutsite': 7156612, 'g2_strand': '+', 'g2_on_site_score': 0.6352101442820706}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'CATATTGACACCAACTCATT', 'PAM_sequence': 'TGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74522226, 'g1_strand': '-', 'g1_on_site_score': 0.35796329769848734, 'g2_chr': 'chr1', 'g2_cutsite': 7159906, 'g2_strand': '-', 'g2_on_site_score': 0.35796329769848734}
{'gene_name': 'OST1', 'gene_id_1': 'g3201.t1', 'gene_id_2': 'g23419.t1', 'sequence': 'CATCCATGAGATCTGCAGGA', 'PAM_sequence': 'AGG', 'occurrence_count': 2, 'g1_chr': 'chr11', 'g1_cutsite': 74519251, 'g1_strand': '+', 'g1_on_site_score': 0.3811753046164073, 'g2_chr': 'chr1', 'g2_cutsite': 7156756, 'g2_strand': '+', 'g2_on_site_score': 0.3811753046164073}
✓ Success! Found 35 validated guides
```csv
gene_name,gene_id_1,gene_id_2,sequence,PAM_sequence,occurrence_count,g1_chr,g1_cutsite,g1_strand,g1_on_site_score,g2_chr,g2_cutsite,g2_strand,g2_on_site_score
TMM,g11664.t1,g33559.t1,AAAGACTGGAAAATCCAACT,GGG,2,chr15,23058534,-,0.4551,chr5,68145613,+,0.4551
TMM,g11664.t1,g33559.t1,ACTTGGTATGCTCCAAAAAC,TGG,2,chr15,23058203,+,0.2809,chr5,68145944,-,0.2809
TMM,g11664.t1,g33559.t1,CAATCAACAGTCAACAAACA,TGG,2,chr15,23057582,+,0.1537,chr5,68146565,-,0.1537
Note: The pipeline outputs guides with an occurrence count of 2, meaning they target both homeologs without additional off-target hits.