/bio-comparative-genomics-ortholog-inference
<!--
$ npx -y skills add FreedomIntelligence/OpenClaw-Medical-Skills --skill bio-comparative-genomics-ortholog-inference --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/bio-comparative-genomics-ortholog-inference
Context preview
The summary Claude sees to decide when to auto-load this skill.
<!--
SKILL.md
bio-comparative-genomics-ortholog-inference.SKILL.md<!--
COPYRIGHT NOTICE
This file is part of the "Universal Biomedical Skills" project.
Copyright (c) 2026 MD BABU MIA, PhD <md.babu.mia@mssm.edu>
All Rights Reserved.
#
This code is proprietary and confidential.
Unauthorized copying of this file, via any medium is strictly prohibited.
#
Provenance: Authenticated by MD BABU MIA
-->
--- name: bio-comparative-genomics-ortholog-inference description: Infer orthologous gene groups across species using OrthoFinder and ProteinOrtho. Identify orthologs, paralogs, and co-orthologs for comparative genomics and functional annotation transfer. Use when identifying gene orthologs across species or building orthogroups for evolutionary analysis. tool_type: cli primary_tool: OrthoFinder measurable_outcome: Execute skill workflow successfully with valid output within 15 minutes. allowed-tools:
- read_file
- run_shell_command
---
Ortholog Inference
OrthoFinder Workflow
'''Ortholog inference with OrthoFinder'''
import subprocess
import pandas as pd
import os
def run_orthofinder(proteome_dir, output_dir=None, threads=4):
'''Run OrthoFinder on directory of proteomes
Input: Directory with one FASTA file per species
File naming: Species name derived from filename
OrthoFinder performs:
1. All-vs-all DIAMOND/BLAST
2. Gene tree inference
3. Species tree inference
4. Ortholog/paralog classification
'''
cmd = f'orthofinder -f {proteome_dir} -t {threads}'
if output_dir:
cmd += f' -o {output_dir}'
# -M msa: Use MSA for gene trees (more accurate but slower)
# -S diamond: Fast search (default)
# -S blast: More sensitive search
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
# Output location
if output_dir:
results_dir = output_dir
else:
# OrthoFinder creates Results_MonDD in proteome_dir
results_dir = None
for d in os.listdir(proteome_dir):
if d.startswith('OrthoFinder/Results_'):
results_dir = os.path.join(proteome_dir, d)
break
return results_dir
def parse_orthogroups(orthogroups_file):
'''Parse OrthoFinder Orthogroups.tsv
Columns: Orthogroup, Species1, Species2, ...
Values: Gene IDs (comma-separated if multiple)
Orthogroup types:
- Single-copy: One gene per species (ideal for phylogenomics)
- Multi-copy: Duplications in some lineages
- Species-specific: Genes unique to one species
'''
df = pd.read_csv(orthogroups_file, sep='\t')
df = df.set_index('Orthogroup')
orthogroups = {}
for og_id, row in df.iterrows():
genes = {}
for species in df.columns:
cell = row[species]
if pd.notna(cell) and cell:
genes[species] = cell.split(', ')
else:
genes[species] = []
orthogroups[og_id] = genes
return orthogroups
def classify_orthogroups(orthogroups, species_list):
'''Classify orthogroups by copy number pattern
Categories:
- single_copy: Exactly one gene per species (best for phylogenomics)
- universal: Present in all species (possibly multicopy)
- partial: Missing from some species
- species_specific: Only in one species
'''
classification = {
'single_copy': [],
'universal': [],
'partial': [],
'species_specific': []
}
for og_id, genes in orthogroups.items():
present_in = [sp for sp in species_list if genes.get(sp)]
copy_counts = [len(genes.get(sp, [])) for sp in species_list]
if len(present_in) == 1:
classification['species_specific'].append(og_id)
elif len(present_in) == len(species_list):
if all(c == 1 for c in copy_counts):
classification['single_copy'].append(og_id)
else:
classification['universal'].append(og_id)
else:
classification['partial'].append(og_id)
return classification
def get_single_copy_orthologs(orthogroups_file):
'''Extract single-copy orthologs for phylogenomics
Single-copy orthologs are ideal because:
- Clear 1:1 relationships
- No paralogy complications
- Suitable for concatenated alignments
'''
df = pd.read_csv(orthogroups_file, sep='\t')
df = df.set_index('Orthogroup')
single_copy = []
for og_id, row in df.iterrows():
is_single = True
for species in df.columns:
cell = row[species]
if pd.isna(cell) or cell == '':
is_single = False
break
if ',' in str(cell):
is_single = False
break
if is_single:
single_copy.append(og_id)
return df.loc[single_copy]Gene Trees and Reconciliation
def parse_gene_trees(gene_trees_dir):
'''Load gene trees from OrthoFinder
Gene trees show evolutionary history within orthogroups
Duplication/loss events inferred by species tree reconciliation
'''
from Bio import Phylo
import glob
trees = {}
for tree_file in glob.glob(f'{gene_trees_dir}/*.txt'):
og_id = os.path.basename(tree_file).replace('_tree.txt', '')
trees[og_id] = Phylo.read(tree_file, 'newick')
return trees
def identify_paralogs(orthogroup, species):
'''Identify in-paralogs within an orthogroup
In-paralogs: Duplications after speciation (within-species)
Out-paralogs: Duplications before speciation (between-species)
Multiple genes from same species in an orthogroup are in-paralogs
'''
genes = orthogroup.get(species, [])
if len(genes) > 1:
return {
'species': species,
'paralogs': genes,
'count': len(genes)
}
return None
def find_co_orthologs(orthogroups, gene_id, species):
'''Find co-orthologs of a gene
Co-orthologs: Multiple genes in one species that areRead more
<!--
COPYRIGHT NOTICE
This file is part of the "Universal Biomedical Skills" project.
Copyright (c) 2026 MD BABU MIA, PhD <md.babu.mia@mssm.edu>
All Rights Reserved.
#
This code is proprietary and confidential.
Unauthorized copying of this file, via any medium is strictly prohibited.
#
Provenance: Authenticated by MD BABU MIA
-->
--- name: bio-comparative-genomics-ortholog-inference description: Infer orthologous gene groups across species using OrthoFinder and ProteinOrtho. Identify orthologs, paralogs, and co-orthologs for comparative genomics and functional annotation transfer. Use when identifying gene orthologs across species or building orthogroups for evolutionary analysis. tool_type: cli primary_tool: OrthoFinder measurable_outcome: Execute skill workflow successfully with valid output within 15 minutes. allowed-tools:
- read_file
- run_shell_command
---
Ortholog Inference
OrthoFinder Workflow
'''Ortholog inference with OrthoFinder'''
import subprocess
import pandas as pd
import os
def run_orthofinder(proteome_dir, output_dir=None, threads=4):
'''Run OrthoFinder on directory of proteomes
Input: Directory with one FASTA file per species
File naming: Species name derived from filename
OrthoFinder performs:
1. All-vs-all DIAMOND/BLAST
2. Gene tree inference
3. Species tree inference
4. Ortholog/paralog classification
'''
cmd = f'orthofinder -f {proteome_dir} -t {threads}'
if output_dir:
cmd += f' -o {output_dir}'
# -M msa: Use MSA for gene trees (more accurate but slower)
# -S diamond: Fast search (default)
# -S blast: More sensitive search
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
# Output location
if output_dir:
results_dir = output_dir
else:
# OrthoFinder creates Results_MonDD in proteome_dir
results_dir = None
for d in os.listdir(proteome_dir):
if d.startswith('OrthoFinder/Results_'):
results_dir = os.path.join(proteome_dir, d)
break
return results_dir
def parse_orthogroups(orthogroups_file):
'''Parse OrthoFinder Orthogroups.tsv
Columns: Orthogroup, Species1, Species2, ...
Values: Gene IDs (comma-separated if multiple)
Orthogroup types:
- Single-copy: One gene per species (ideal for phylogenomics)
- Multi-copy: Duplications in some lineages
- Species-specific: Genes unique to one species
'''
df = pd.read_csv(orthogroups_file, sep='\t')
df = df.set_index('Orthogroup')
orthogroups = {}
for og_id, row in df.iterrows():
genes = {}
for species in df.columns:
cell = row[species]
if pd.notna(cell) and cell:
genes[species] = cell.split(', ')
else:
genes[species] = []
orthogroups[og_id] = genes
return orthogroups
def classify_orthogroups(orthogroups, species_list):
'''Classify orthogroups by copy number pattern
Categories:
- single_copy: Exactly one gene per species (best for phylogenomics)
- universal: Present in all species (possibly multicopy)
- partial: Missing from some species
- species_specific: Only in one species
'''
classification = {
'single_copy': [],
'universal': [],
'partial': [],
'species_specific': []
}
for og_id, genes in orthogroups.items():
present_in = [sp for sp in species_list if genes.get(sp)]
copy_counts = [len(genes.get(sp, [])) for sp in species_list]
if len(present_in) == 1:
classification['species_specific'].append(og_id)
elif len(present_in) == len(species_list):
if all(c == 1 for c in copy_counts):
classification['single_copy'].append(og_id)
else:
classification['universal'].append(og_id)
else:
classification['partial'].append(og_id)
return classification
def get_single_copy_orthologs(orthogroups_file):
'''Extract single-copy orthologs for phylogenomics
Single-copy orthologs are ideal because:
- Clear 1:1 relationships
- No paralogy complications
- Suitable for concatenated alignments
'''
df = pd.read_csv(orthogroups_file, sep='\t')
df = df.set_index('Orthogroup')
single_copy = []
for og_id, row in df.iterrows():
is_single = True
for species in df.columns:
cell = row[species]
if pd.isna(cell) or cell == '':
is_single = False
break
if ',' in str(cell):
is_single = False
break
if is_single:
single_copy.append(og_id)
return df.loc[single_copy]Gene Trees and Reconciliation
def parse_gene_trees(gene_trees_dir):
'''Load gene trees from OrthoFinder
Gene trees show evolutionary history within orthogroups
Duplication/loss events inferred by species tree reconciliation
'''
from Bio import Phylo
import glob
trees = {}
for tree_file in glob.glob(f'{gene_trees_dir}/*.txt'):
og_id = os.path.basename(tree_file).replace('_tree.txt', '')
trees[og_id] = Phylo.read(tree_file, 'newick')
return trees
def identify_paralogs(orthogroup, species):
'''Identify in-paralogs within an orthogroup
In-paralogs: Duplications after speciation (within-species)
Out-paralogs: Duplications before speciation (between-species)
Multiple genes from same species in an orthogroup are in-paralogs
'''
genes = orthogroup.get(species, [])
if len(genes) > 1:
return {
'species': species,
'paralogs': genes,
'count': len(genes)
}
return None
def find_co_orthologs(orthogroups, gene_id, species):
'''Find co-orthologs of a gene
Co-orthologs: Multiple genes in one species that areThe largest open-source medical AI skill library for OpenClaw.
Other skills on openclaw-medical-skills.
adaptyv
Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding…
adhd-daily-planner
Time-blind friendly planning, executive function support, and daily structure for ADHD brains. Specializes in realistic time estimation, dopamine-aware task…
aeon
This skill should be used for time series machine learning tasks including classification, regression, clustering, forecasting, anomaly detection,…
agent-browser
Browse the web for any task — research topics, read articles, interact with web apps, fill forms, take screenshots, extract data, and test web pages. Use…

