These four commands download the latest Linux installer (for your chosen architecture), rename it to a shorter file name, perform a silent install, and then delete the installer:
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm ~/miniconda3/miniconda.sh
After installing, close and reopen your terminal application or refresh it by running the following command:
source ~/miniconda3/bin/activate
To initialize conda on all available shells, run the following command:
conda init --all
Desde linea de comandos de un cluster Linux, en el que no soy administrador, he instalado miniconda y con "source ~/miniconda3/bin/activate" consigo que aparezca (base), pero al salir de la sesion y entrar de nuevo en ella tengo que repetir esta sentencia, ¿cómo consigo que siempre me aparezca (base) sin usar source "source ~/miniconda3/bin/activate" cada vez que abro mi sesion por SSH?
Edita el archivo de configuración del shell y añade la al final del archivo la línea inferior siguiente:
nano ~/.bashrc
source ~/miniconda3/bin/activate
Crear un entorno virtual llamado "RD-openbabel"
Open Babel 3.1.1 (o versiones más recientes) requiere al menos Python 3.7 para instalar y utilizar la biblioteca. Puedes crear un nuevo entorno en Miniconda con una versión compatible de Python, como Python 3.8 o superior:
conda create -n RD-openbabel python=3.8
conda activate RD-openbabel
conda install -c conda-forge openbabel
¿cómo verifico que tengo instalado openbabel?
obabel -V
Open Babel 3.1.0 -- Nov 30 2023 -- 20:44:30
Instalar RDKit, tqdm, y AutoDock Vina 1.2.5 en mi nuevo entorno de Miniconda llamado "RD-openbabel".
conda install -c conda-forge rdkit tqdm
conda install -c conda-forge vina=1.2.5
Después de instalar, puedes verificar que todo funciona correctamente:
python -c "import rdkit; print(rdkit.__version__)"
python -c "import tqdm; print(tqdm.__version__)"
vina --version
obabel -V
conda env list
conda list
Script para generar todos estereoisómeros posibles de una molécula con carbonos quirales.
Necesitas tener instalado en tu entorno virtual RDkit y OpenBabel. Puedes ejecutar este script en Windows o en Linux simplemente comentando (#) la ruta que no quieras usar.
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem.EnumerateStereoisomers import EnumerateStereoisomers, StereoEnumerationOptions
import os
# Define input and output directories
input_directory = r'/home/jant/runQuiral/01/' # Update with your path
output_directory = os.path.join(input_directory, 'isomers')
os.makedirs(output_directory, exist_ok=True)
# Function to clear stereochemistry assignments
def clear_stereochemistry(mol):
"""Removes CIP codes and resets chiral centers to unspecified."""
for atom in mol.GetAtoms():
if atom.HasProp('_CIPCode'): # Clear CIP codes
atom.ClearProp('_CIPCode')
atom.SetChiralTag(Chem.rdchem.ChiralType.CHI_UNSPECIFIED)
# Function to generate stereoisomers and minimize their energy
def process_molecules(input_directory, output_directory):
"""Processes all SDF files in the input directory, generating stereoisomers."""
for file_name in os.listdir(input_directory):
if file_name.endswith('.sdf'):
input_file_path = os.path.join(input_directory, file_name)
output_file_path = os.path.join(output_directory, file_name.replace('.sdf', '_isomers.sdf'))
# Skip molecules that have already been processed
if os.path.exists(output_file_path) and os.path.getsize(output_file_path) > 0:
print(f"Skipping {file_name}: isomers file already exists.")
continue
suppl = Chem.SDMolSupplier(input_file_path)
molecules = [mol for mol in suppl if mol is not None]
if not molecules:
print(f"No valid molecules found in {file_name}. Skipping.")
continue
writer = Chem.SDWriter(output_file_path)
for mol in molecules:
chiral_centers = Chem.FindMolChiralCenters(mol, includeUnassigned=True)
num_centers = len(chiral_centers)
if num_centers > 4:
print(f"Skipping {Chem.MolToSmiles(mol)}: more than 4 chiral centers.")
open(output_file_path, 'w').close() # Create an empty file
continue
# Work on a copy to avoid modifying the original molecule
mol_copy = Chem.Mol(mol)
clear_stereochemistry(mol_copy)
# Generate stereoisomers
opts = StereoEnumerationOptions(tryEmbedding=True)
isomers = tuple(EnumerateStereoisomers(mol_copy, options=opts))
num_isomers = len(isomers)
print(f"Found {num_isomers} isomers for {Chem.MolToSmiles(mol)}")
# Print SMILES of isomers
print("Isomer SMILES:")
for smi in sorted(Chem.MolToSmiles(x, isomericSmiles=True) for x in isomers):
print(f" {smi}")
# Get molecule base name
base_name = mol.GetProp("_Name") if mol.HasProp("_Name") else file_name.replace('.sdf', '')
for idx, isomer in enumerate(isomers, start=1):
isomer_name = f"{base_name}_{idx}"
isomer.SetProp("_Name", isomer_name)
isomer = Chem.AddHs(isomer) # Add hydrogen atoms
try:
AllChem.EmbedMolecule(isomer, AllChem.ETKDG()) # Generate 3D coordinates
AllChem.MMFFOptimizeMolecule(isomer, mmffVariant='MMFF94s') # Energy minimization
except Exception as e:
print(f"Energy minimization failed for {isomer_name}: {e}")
continue
writer.write(isomer)
writer.close()
print(f"Isomers for {file_name} saved to {output_file_path}")
# Run the function
process_molecules(input_directory, output_directory)
print(f"All isomers have been generated and saved in {output_directory}")
Si tienes varios miles de ficheros *.sdf y para trabajar en paralelo, divídelos en 8 grupos, en este ejemplo:
import os
import shutil
from math import ceil
# Quiero dividir 960,000 ficheros *.sdf en 8 grupos para que sea más fácil trabajar con ellos.
# Nombre del script: 05-distribuir_sdfs_8_grupos.py
# Ejecución: Windows, fecha creacción de esta versión: 2025-01-28
# Ruta base
ruta_base = r"D:\aaa"
# Cambiar aquí para ajustar el número de grupos (8 en este caso)
num_grupos = 8
carpetas_destino = [os.path.join(ruta_base, f"{i:02}") for i in range(1, num_grupos + 1)]
# Crear carpetas de destino si no existen
for carpeta in carpetas_destino:
os.makedirs(carpeta, exist_ok=True)
# Listar los archivos .sdf en la ruta base
archivos_sdf = [f for f in os.listdir(ruta_base) if f.endswith(".sdf")]
# Calcular el número de archivos por grupo
n_archivos = len(archivos_sdf)
if n_archivos == 0:
print("No se encontraron archivos .sdf en la ruta especificada.")
else:
# Cambiar aquí para ajustar el número de grupos (8 en este caso)
archivos_por_grupo = ceil(n_archivos / num_grupos)
# Distribuir y copiar archivos
for i, archivo in enumerate(archivos_sdf):
grupo = i // archivos_por_grupo # Determinar a qué grupo pertenece
destino = carpetas_destino[grupo] # Carpeta de destino correspondiente
origen = os.path.join(ruta_base, archivo)
shutil.copy(origen, destino) # Copiar archivo
print(f"Archivo {archivo} copiado a {destino}")
print(f"Se distribuyeron {n_archivos} archivos .sdf en {num_grupos} grupos.")