Structure

Descrição

De acordo com a página do Structure, o programa structure é um pacote de software livre para usar dados genotípicos multi-locus para investigar estrutura populacional. Seus usos incluem inferir a presença de populações distintas, atribuir indivíduos a populações, estudar zonas híbridas, identificar migrantes e indivíduos miscigenados, e estimar frequências alélicas populacionais.

Versões Disponíveis

  • structure/2.3.4 (default)

Carregando o Módulo

# Carregar Structure
module load structure/2.3.4

# Verificar instalação
structure -h

Submissão de Jobs

submit_structure.sh
#!/bin/bash
#SBATCH -J structure
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 24:00:00
#SBATCH --mem=8G

export INPUT="input"
export OUTPUT="output_K5"

module load structure/2.3.4

job-nanny structure -K 5 -o output_K5

Job Array para Múltiplos Valores de K

submit_structure_array.sh
#!/bin/bash
#SBATCH -J structure_array
#SBATCH --array=1-10
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 24:00:00
#SBATCH --mem=8G

K=$SLURM_ARRAY_TASK_ID
export INPUT="input"
export OUTPUT="output_K${K}/"

module load structure/2.3.4

mkdir -p output_K${K}
cd output_K${K}
cp ../input .

job-nanny structure -K $K -o output

Múltiplas Execuções para Cada K

submit_structure_replicates.sh
#!/bin/bash
#SBATCH -J structure_reps
#SBATCH --array=1-50
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 24:00:00
#SBATCH --mem=8G

# 5 valores de K × 10 réplicas
K=$(( (SLURM_ARRAY_TASK_ID-1) / 10 + 1 ))
REP=$(( (SLURM_ARRAY_TASK_ID-1) % 10 + 1 ))

export INPUT="input"
export OUTPUT="K${K}_rep${REP}/"

module load structure/2.3.4

mkdir -p K${K}_rep${REP}
cd K${K}_rep${REP}
cp ../input .

# Diferentes sementes para cada réplica
SEED=$((12345 + SLURM_ARRAY_TASK_ID))

job-nanny structure -K $K -o output -D $SEED

Arquivo de Entrada (mainparams)

mainparams
#define INFILE input
#define OUTFILE structure_out
#define NUMINDS 100
#define NUMLOCI 10
#define PLOIDY 2
#define MISSING -9
#define ONEROWPERIND 0
#define LABEL 1
#define POPDATA 1
#define POPFLAG 0
#define LOCDATA 0
#define PHENOTYPE 0
#define EXTRACOLS 0
#define MARKERNAMES 1
#define RECESSIVEALLELES 0
#define MAPDISTANCES 0

Arquivo de Entrada (extraparams)

extraparams
#define BURNIN 10000
#define NUMREPS 20000
#define NOADMIX 0
#define LINKAGE 0
#define USEPOPINFO 0
#define LOCPRIOR 0
#define FREQSCORR 1
#define ONEFST 0
#define INFERALPHA 1
#define POPALPHAS 0
#define ALPHA 1.0
#define INFERLAMBDA 0
#define LAMBDA 1.0
#define COMPUTEPROB 1
#define PFROMPOPFLAGONLY 0
#define ANCESTDIST 0
#define STARTATPOPINFO 0
#define METROFREQ 10
#define UPDATEFREQ 1

Arquivo de Dados

input
1 1 1 2 2 2
1 2 1 1 2 2
2 1 2 2 1 1
2 2 1 1 1 2
1 1 2 2 2 1
2 1 1 2 1 2

Formato: Linhas representam indivíduos, colunas representam loci, com genótipos codificados.

Análise de Resultados

analyze_structure.sh
#!/bin/bash
#SBATCH -J analyze_structure
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 02:00:00
#SBATCH --mem=4G

module load R/4.0.2

# Criar script de análise
cat > analyze_structure.R << 'EOF'
library(ggplot2)
library(dplyr)

# Coletar resultados para diferentes K
results <- data.frame()

for (k in 1:10) {
    files <- list.files(pattern = paste0("K", k, "_rep.*/output_f"),
                       recursive = TRUE, full.names = TRUE)

    if (length(files) > 0) {
        # Extrair likelihoods
        for (f in files) {
            lines <- readLines(f)
            like_line <- grep("Estimated Ln Prob of Data", lines, value=TRUE)
            if (length(like_line) > 0) {
                like <- as.numeric(gsub(".*= ", "", like_line))
                results <- rbind(results, data.frame(K=k, Likelihood=like))
            }
        }
    }
}

# Plotar likelihood médio por K
summary <- results %>%
    group_by(K) %>%
    summarise(mean_like = mean(Likelihood, na.rm=TRUE),
              sd_like = sd(Likelihood, na.rm=TRUE),
              n = n())

p <- ggplot(summary, aes(x=K, y=mean_like)) +
     geom_point(size=3) +
     geom_line() +
     geom_errorbar(aes(ymin=mean_like-sd_like, ymax=mean_like+sd_like), width=0.2) +
     theme_minimal() +
     labs(title="Likelihood por K", x="K", y="Likelihood média")

ggsave("likelihood_plot.png", p, width=8, height=6)

# Estatísticas de Evanno (delta K)
if (nrow(summary) > 2) {
    summary$L_prime <- c(NA, diff(summary$mean_like))
    summary$L_doubleprime <- c(NA, diff(summary$L_prime), NA)
    summary$deltaK <- abs(summary$L_doubleprime) / summary$sd_like

    write.csv(summary, "evanno_stats.csv", row.names=FALSE)

    p2 <- ggplot(summary, aes(x=K, y=deltaK)) +
          geom_point(size=3) +
          geom_line() +
          theme_minimal() +
          labs(title="Delta K (Evanno)", x="K", y="Delta K")

    ggsave("deltaK_plot.png", p2, width=8, height=6)
}
EOF

Rscript analyze_structure.R

Plot de Q-matrices

plot_qmatrix.sh
#!/bin/bash
#SBATCH -J plot_qmatrix
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 01:00:00
#SBATCH --mem=2G

module load R/4.0.2

cat > plot_q.R << 'EOF'
library(ggplot2)
library(reshape2)

# Ler arquivo de resultados do Structure (formato Q)
read_structure_q <- function(file, K) {
    lines <- readLines(file)
    # Pular cabeçalho
    data_lines <- lines[grep("^[0-9]", lines)]

    q_matrix <- matrix(0, nrow=length(data_lines), ncol=K)
    for (i in 1:length(data_lines)) {
        vals <- as.numeric(strsplit(data_lines[i], "\\s+")[[1]])
        q_matrix[i,] <- vals[length(vals) - (K-1):0]
    }

    return(q_matrix)
}

# Exemplo para K=3
q <- read_structure_q("output_K3/output_f", 3)

df <- melt(q)
colnames(df) <- c("Individuo", "Populacao", "Proporcao")
df$Populacao <- factor(df$Populacao)

p <- ggplot(df, aes(x=Individuo, y=Proporcao, fill=Populacao)) +
     geom_bar(stat="identity", width=1) +
     theme_minimal() +
     labs(title="Estrutura populacional (K=3)",
          x="Indivíduo", y="Proporção") +
     scale_fill_brewer(palette="Set1")

ggsave("structure_plot_K3.png", p, width=12, height=4)
EOF

Rscript plot_q.R

Referências

Ver também