Metodologia "contém gene" - danifilho/Evo2_BASF GitHub Wiki
to_std.awk
BEGIN{FS=OFS="\t";
map["NC_003070.9"]="1"; map["NC_003071.7"]="2"; map["NC_003074.8"]="3";
map["NC_003075.7"]="4"; map["NC_003076.8"]="5"; map["NC_000932.1"]="C";
map["NC_037304.1"]="M"; # organelos
map["Chr1"]="1"; map["Chr2"]="2"; map["Chr3"]="3"; map["Chr4"]="4";
map["Chr5"]="5"; map["ChrC"]="C"; map["ChrM"]="M";
}
{if($1 in map) $1=map[$1]; print}
awk -f to_std.awk INFILE > OUT_STD.bed
Carregando o modulo
module load BEDTools/2.31.0-GCC-12.3.0
# 3.1 149 952 bp (≈150 kb)
bedtools makewindows -g TAIR10.fna.fai -w 149952 \
| awk -f to_std.awk > windows149k_std.bed # 1…5 C M
# 3.2 128 bp
bedtools makewindows -g TAIR10.fna.fai -w 128 \
| awk -f to_std.awk > tmp128.bed
awk 'BEGIN{FS=OFS="\t"}{print $0,"win128_"NR}' tmp128.bed > windows128_std.bed
rm tmp128.bed
grep -P '\tgene\t' TAIR10.gff3 \
| awk -f to_std.awk > genes_only_std.gff3
bedtools intersect -u \
-a windows149k_std.bed \
-b genes_only_std.gff3 \
> gene_win.bed
bedtools intersect -u \
-a windows128_std.bed \
-b gene_win.bed \
> hits_gene_embed.bed
Criando o X.npy
salloc -p intel18 -N1 -w skl-141 -c 32 --mem=0 -t 02:00:00 -J prep_evo2
module purge
module load foss/2023a
module load BEDTools/2.31.0-GCC-12.3.0
python -m pip install --no-cache-dir \
"numpy<2" pandas tqdm "torch==2.2.2+cpu" \
-f https://download.pytorch.org/whl/torch_stable.html
#!/usr/bin/env python
"""
make_X.py
Cria X.npy (float32 memmap) e meta.tsv usando embeddings Evo2-7B
de shards de 149 952 bp. RAM (~3 GB) • tempo ~30 min (32 CPU).
"""
from pathlib import Path
import torch, numpy as np, pandas as pd
from tqdm import tqdm
# ── parâmetros ─────────────────────────────────────────────────────────────
WIN = 128
EMB_DIR = Path("/mnt/gs21/scratch/dasilvaf/evo2/create_embeddings/embeddings_149952_full") # ajuste se necessário
OUT_X = Path("X.npy")
OUT_META= Path("meta.tsv")
# ── descobrir shape global ─────────────────────────────────────────────────
shards = sorted([p for p in EMB_DIR.glob("*.pt")
if int(p.stem.rsplit("_",2)[2]) - int(p.stem.rsplit("_",2)[1]) == 149_952])
d = torch.load(shards[0], map_location="cpu").shape[1]
N = len(shards) * (149_952 // WIN) # 1171 janelas por shard
print(f"{len(shards)} shards · {N:,} janelas · d = {d}")
# ── memmap de saída ────────────────────────────────────────────────────────
X_mm = np.memmap(OUT_X, dtype="float32", mode="w+", shape=(N, d))
meta_rows, ptr = [], 0
# ── processar shards ───────────────────────────────────────────────────────
for sh in tqdm(shards, desc="embeddings"):
raw = torch.load(sh, map_location="cpu").float() # (149 952, d)
n_win = raw.shape[0] // WIN # 1171
tens = raw[: n_win*WIN].view(n_win, WIN, d).mean(dim=1).numpy()
ids = [f"{sh.stem}::{i}" for i in range(n_win)]
X_mm[ptr:ptr+n_win] = tens
meta_rows.extend({"id": uid} for uid in ids)
ptr += n_win
# ── salvar metadados ───────────────────────────────────────────────────────
pd.DataFrame(meta_rows).to_csv(OUT_META, sep="\t", index=False)
print("✔️ X.npy e meta.tsv criados")
dasilvaf@skl-141:/mnt/gs21/scratch/dasilvaf/evo2/create_dataset/gene_methodology$ python make_X.py
1584 shards · 1,854,864 janelas · d = 4096
embeddings: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1584/1584 [50:12<00:00, 1.90s/it]
✔️ X.npy e meta.tsv criados
Criando o y_gene.py
#!/usr/bin/env python
# make_y_gene.py ------------------------------------------------------------
"""
Gera y_gene.npy (rótulo 0/1) usando:
• windows_std.bed (janelas 128 bp, IDs shard::idx, cromossomos 1-5 C M)
• windows149k_std.bed (janelas 150 kb)
• genes_only_std.gff3 (genes TAIR padronizados)
Saída: y_gene.npy – vetor uint8 alinhado a X.npy / meta.tsv
"""
from pathlib import Path
import subprocess, numpy as np, pandas as pd
WIN128 = Path("windows_std.bed")
WIN150 = Path("windows149k_std.bed")
GENES = Path("genes_only_std.gff3")
GENE_WIN = Path("gene_win.bed") # 150 kb com ≥1 gene
HITS_BED = Path("hits_gene_embed.bed") # 128 bp positivos
META = Path("meta.tsv")
OUT_YG = Path("y_gene.npy")
# 1) janelas 150 kb que contêm gene -----------------------------------------
subprocess.check_call(
["bedtools","intersect","-u",
"-a", str(WIN150), "-b", str(GENES)],
stdout=GENE_WIN.open("w")
)
# 2) janelas 128 bp dentro dessas 150 kb ------------------------------------
subprocess.check_call(
["bedtools","intersect","-u",
"-a", str(WIN128), "-b", str(GENE_WIN)],
stdout=HITS_BED.open("w")
)
hit_ids = {l.split("\t")[3].strip() for l in HITS_BED.open()}
# 3) vetor de rótulos --------------------------------------------------------
meta = pd.read_csv(META, sep="\t")
y_gene = np.fromiter((uid in hit_ids for uid in meta.id),
dtype="uint8", count=len(meta))
np.save(OUT_YG, y_gene)
print("✔️ y_gene.npy salvo – % positivos =", y_gene.mean()*100)
y_gene.npy salvo – % positivos = 99.24269380396622
-
Motivação Se uma janela de 150 kb contém pelo menos um gene, há grande chance de haver algum elemento regulatório ativo (CRE) dentro dela. Resultado: rótulo positivo = “janela 128 bp está dentro de uma janela 150 kb que contém gene”.
-
Conversão das
bedtools makewindows -g ../evo2_arabidopsis/GCF_000001735.4_TAIR10.1_genomic.fna.fai -w 149952 > windows149k.bed
149 952 bp equivale a 1 171 tokens de 128 bp no Evo2.
- Padronização de cromossomos
- Da mesma forma, criei um awk que converteu IDs NCBI → TAIR10 (Chr1…Chr5 ChrC ChrM).
- Arquivo resultante: windows149k_chr.bed.
awk 'BEGIN{
FS = OFS = "\t"; # TAB como separador
# ── mapa NCBI → TAIR10 ──────────────────────────
map["NC_003070.9"] = "Chr1"; # cromossomos 1–5
map["NC_003071.7"] = "Chr2";
map["NC_003074.8"] = "Chr3";
map["NC_003075.7"] = "Chr4";
map["NC_003076.8"] = "Chr5";
map["NC_000932.1"] = "ChrC"; # cloroplasto
map["NC_037304.1"] = "ChrM"; # mitocôndria
}
{
if ($1 in map) $1 = map[$1]; # converte se estiver no mapa
print # devolve a linha TAB-delimitada
}' windows149k.bed > windows149k_chr.bed
- Seleção de janelas que contêm genes
grep -P '\tgene\t' TAIR10_GFF3_genes.gff > genes_only.gff3
bedtools intersect -u -a windows149k_chr.bed -b genes_only.gff3 > gene_win.bed
- gene_win.bed = subconjunto de janelas 150 kb com ≥1 gene
- Janelas pequenas de 128 bp
- Geramos de novo o BED de 128 bp:
bedtools makewindows -g TAIR10.fna.fai -w 128 > windows128.bed
- Mesma conversão de cromossomos + coluna-ID → windows128_chr.bed.
- Propagação do rótulo
bedtools intersect -u \
-a windows128_chr.bed \
-b gene_win.bed \
> hits128_gene.bed
- hits128_gene.bed contém só as linhas 128 bp que caem em janelas 150 kb com gene.
- IDs positivos ≈ 90 % das janelas (genoma de Arabidopsis é gene-denso).
- Checagens
- Conferimos contigs no .fai: 5 nucleares + cloroplasto (NC_000932.1) + mitocôndria (NC_037304.1).
- Verificamos que todos os BEDs usam Chr1…Chr5 ChrC ChrM.
- cut -f4 hits128_gene.bed | sort | uniq -d → nenhum ID duplicado.
Eu tive problemas para gerar o y_genes.npy por conta do arquivo windows.bed, que está com os cromossomos identificados por 1, 2, 3, 4, 5, C e M, ao invés da anotação que estou usando. Agora, cirei outro arquivo hits_gene_embed.bed com a anotação correta com
# usa o BED de embeddings (windows.bed) vs. janelas-gene
bedtools intersect -u \
-a windows.bed \
-b gene_win.bed \
> hits_gene_embed.bed