Scripts de Python 3 para agilizar la ejecución de simulaciones de dinámica molecular en Linux con SLURM.

Primero planteemos la situación: tenemos varios complejos proteina-ligando acoplado y queremos hacer, con cada uno de ellos, una simulación de dinámica molecular; usando el software YASARA structure, ejecutado en un cluster de computación que tenga, como gestor de colas de trabajos, SLURM. A continuación se muestran los scripts de Python 3 que agilizan todo el proceso. Deben editarse de acuerdo con las diferentes rutas y ejecutarse secuencialmente. Todo este proceso no es automático, requiere que quien lo ejecute comprenda lo que está haciendo.

Primero ejecutaremos scripts "RUN" para realizar las simulaciones de dinámica molecular, después podremos calcular la energia de unión (MM|PBSA por ejemplo), con scripts "BIN", y finalmente, podremos ejecutar los análisis de RMSD, etc; con los scripts "ANA".

Para lanzar cada trabajo de cómputo usaremos un script 'sbatch', de modo que si tenemos que lanzar 100 trabajos, tendríamos que escribir otros tantos ficheros de texto con las instrucciones para ejecutar cada trabajo. Luego para ser eficaces debemos automatizar este proceso. Empezaremos por crear un fichero de texto plano con información en al menos 3 columnas: columna 1, con el nombre del trabajo que aparecerá cuando desde la consola Linux tecleemos squeue; columna 2, con los nombres de cada carpeta donde se ejecutará cada trabajo de cálculo; y columna 3, con los nombres de cada fichero PDB, SCE o JOB; que puede leer YASARA para iniciar una simulación de dinámica molecular. Justo debajo puede verse un ejemplo de fichero _lista-4-variables-en-4-columnas.txt con 3 variables en columnas separadas por tabuladores. Podria añadir tantas variables como necesite en otras tantas columnas separadas por tabuladores.

Aquí tenemos un ejemplo de _lista-4-variables-en-4-columnas.txt:

MD001	MD001_MP369-370clean-1383	MD001_MP369-370clean-1383	
MD002	MD002_MP407-408clean-870	MD002_MP407-408clean-870	
MD003	MD003_MP407-408clean-872	MD003_MP407-408clean-872	
MD004	MD004_MP407-408clean-889	MD004_MP407-408clean-889	
MD005	MD005_MP407-408clean-894	MD005_MP407-408clean-894	
MD006	MD006_MP407-408clean-901	MD006_MP407-408clean-901	
MD007	MD007_MP271-272clean-1468	MD007_MP271-272clean-1468	
MD008	MD008_MP325-326clean-1696	MD008_MP325-326clean-1696	
MD009	MD009_MP325-326clean-1700	MD009_MP325-326clean-1700	
MD010	MD010_MP325-326clean-1710	MD010_MP325-326clean-1710	

A continuación se muestra la plantilla que permitirá a Python crear tantos ficheros *.sbatch como filas tenga nuestro fichero _lista-4-variables-en-4-columnas.txt, en nuestro ejemplo 10.

Fichero de plantilla con nombre y ruta: /home/jant.encinar/py-linux/10_template_variable/_10c-template-config-ALB_RUN.txt

#!/bin/bash
#SBATCH --job-name=run[variable-1]
#SBATCH --cpus-per-task=24
#SBATCH --mem=4G
#SBATCH --time=7-0
#SBATCH --qos=long
#SBATCH --output=/home/jant.encinar/runMDs/[variable-2]/ab_salida-%j.out
#SBATCH --error=/home/jant.encinar/runMDs/[variable-2]/ab_error-%j.err
  
/home/jant.encinar/yasara-22.5.22/yasara -txt /home/jant.encinar/runMDs/_sbatch-UMH/_md_analyze_ligand.mcr "MacroTarget='/home/jant.encinar/runMDs/[variable-2]/[variable-3]'"

El siguiente script de Python 3 llamado (10c_template_variable_RUN.py y localizado en la ruta "/home/jant.encinar/py-linux/10_template_variable/") usará la información contenida en el fichero de texto "/home/jant.encinar/py-linux/10_template_variable/_lista-4-variables-en-4-columnas.txt" de cada variable y el fichero de plantilla (_10c-template-config-ALB_RUN.txt) para generar en la ruta "/home/jant.encinar/py-linux/10_template_variable/" 10 ficheros con extensión *.sbatch y nombre de cada fila de la primera columna.

# -*- coding: iso-8859-1 -*-
import os

# Ruta y nombre de archivo de la lista de variables
var_file_path = '/home/jant.encinar/py-linux/10_template_variable/_lista-4-variables-en-4-columnas.txt'

# Ruta y nombre de archivo de la plantilla de configuración
template_file_path = '/home/jant.encinar/py-linux/10_template_variable/_10c-template-config-ALB_RUN.txt'

# Abrir el archivo de variables y leer las líneas
with open(var_file_path, 'r') as var_file:
    var_lines = var_file.readlines()

# Para cada línea de variables, generar una nueva plantilla con las variables sustituidas
for line in var_lines:
    # Separar las variables por tabuladores y eliminar cualquier espacio en blanco
    variables = [var.strip() for var in line.split('\t')]

    # Leer la plantilla de configuración y sustituir las variables
    with open(template_file_path, 'r') as template_file:
        template = template_file.read()
        for i in range(len(variables)):
            template = template.replace(f'[variable-{i+1}]', variables[i])

    # Guardar el archivo de configuración generado con el nombre de la primera variable y la extensión ".sbatch"
    output_file_path = f"/home/jant.encinar/py-linux/10_template_variable/run{variables[0]}.sbatch"
    with open(output_file_path, 'w') as output_file:
        output_file.write(template)

print("Proceso completado con éxito!")

Aquí tenemos un ejemplo del contenido del fichero runMD001.sbatch:

Para hacer más agil el lanzamiento de todos los ficheros *.sbatch de ejecución de las 10 simulaciones (siguiendo con nuestro ejemplo anterior) de dinámica molecular, usaremos el siguiente script de Python 3 (10f_template_run_sh.py) para generar un fichero "_alanzar-RUN.sh" que ejecutado desde consola lance los 10 trabajos de simulación al sistema de gestión de colas de SLURN que tiene nuestro cluster de cómputo.

# -*- coding: iso-8859-1 -*-
import os
import glob

folder_path = "/home/jant.encinar/py-linux/10_template_variable/"
file_pattern = "run" # busca todos los ficheros cuyo nombre empieza por "run"

files = glob.glob(os.path.join(folder_path, file_pattern + "*"))
files = sorted(files)  # Ordenar la lista de nombres de archivo

with open("_alanzar-RUN.sh", "w") as f:
    for filename in files:
        if os.path.isfile(filename) and filename.startswith(os.path.join(folder_path, file_pattern)):
            f.write(f"sbatch {filename}\n")
os.chmod("_alanzar-RUN.sh", 0o777)  # establecer permisos en 777 para lectura, escritura y ejecución.

A continuación se muestra el contenido del fichero generado ("_alanzar-RUN.sh"), que además ya tiene permisos de ejecución:

sbatch /home/jant.encinar/py-linux/10_template_variable/runMD001.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD002.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD003.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD004.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD005.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD006.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD007.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD008.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD009.sbatch
sbatch /home/jant.encinar/py-linux/10_template_variable/runMD010.sbatch

La ejecución desde consola ya es sencilla:

sh _alanzar-RUN.sh