Python

Tema 6 · Descriptors moleculars

Introducció

Els descriptors moleculars són propietats fisicoquímiques o estructurals d'una molècula que es poden calcular a partir de la seva representació (SMILES, SDF, etc.). Descriuen característiques com el pes molecular, la lipofília (LogP), els enllaços d'hidrogen, la superfície polar, etc. Aquests descriptors s'utilitzen en models QSAR, filtrat de compostos i optimització de fàrmacs.

Objectius

  • Entendre què són els descriptors moleculars i per a què serveixen
  • Calcular descriptors bàsics (MW, LogP, HBA, HBD) amb Python
  • Utilitzar RDKit (si està disponible) o fórmules aproximades per a càlculs senzills
  • Crear un conjunt de descriptors a partir d'un fitxer CSV de molècules

Càlcul de descriptors bàsics

Exemple amb RDKit (llibreria de quimioinformàtica) per calcular descriptors a partir d'un SMILES:

# Si tens RDKit instal·lat (conda install -c conda-forge rdkit)
from rdkit import Chem
from rdkit.Chem import Descriptors, Crippen

smiles = "CC(C)CC1=CC=C(C=C1)C(C)C(=O)O"  # Ibuprofè
mol = Chem.MolFromSmiles(smiles)

if mol:
    mw = Descriptors.MolWt(mol)
    logp = Crippen.MolLogP(mol)
    hba = Descriptors.NumHAcceptors(mol)
    hbd = Descriptors.NumHDonors(mol)
    print(f"MW: {mw:.1f}, LogP: {logp:.2f}, HBA: {hba}, HBD: {hbd}")
else:
    print("SMILES no vàlid")
RDKit pot calcular centenars de descriptors

Si no tens RDKit, pots fer servir fórmules empíriques per a molècules senzilles:

def estimar_mw(formula):
    """Estima el pes molecular a partir d'una fórmula simplificada."""
    pesos = {'C':12.01, 'H':1.008, 'O':16.00, 'N':14.01, 'S':32.07}
    # Exemple molt simplificat: "C13H18O2" (ibuprofè)
    # En la pràctica caldria analitzar la fórmula real
    return sum(pesos.get(elem,0)*int(num) for elem,num in 
               [('C',13),('H',18),('O',2)])

# Càlcul ràpid del nombre d'àtoms acceptors/donadors d'H
def compta_heteroatoms(smiles):
    acceptors = smiles.count('O') + smiles.count('N')
    donadors = smiles.count('[NH]') + smiles.count('[OH]')  # simplificat
    return acceptors, donadors

Aplicació a un dataset amb Pandas

Integrant Pandas i RDKit per calcular descriptors de moltes molècules alhora:

import pandas as pd
# Suposem df amb columna 'SMILES'
def calcular_descriptors(smiles):
    from rdkit import Chem
    from rdkit.Chem import Descriptors, Crippen
    mol = Chem.MolFromSmiles(smiles)
    if mol:
        return pd.Series({
            'MW': Descriptors.MolWt(mol),
            'LogP': Crippen.MolLogP(mol),
            'HBA': Descriptors.NumHAcceptors(mol),
            'HBD': Descriptors.NumHDonors(mol),
            'ROTB': Descriptors.NumRotatableBonds(mol)
        })
    else:
        return pd.Series()

# Aplicar a totes les files
df_descriptors = df['SMILES'].apply(calcular_descriptors)
df = pd.concat([df, df_descriptors], axis=1)
df.to_csv('molecules_descriptors.csv', index=False)

Exercicis

  1. A partir d'un SMILES d'exemple (aspirina: CC(=O)Oc1ccccc1C(=O)O), calcula manualment el nombre d'acceptors i donadors d'enllaços d'hidrogen.
  2. Utilitza RDKit per generar una taula de descriptors de 10 molècules i guarda-la en un CSV.
  3. Dibuixa amb Matplotlib la distribució de pesos moleculars d'una biblioteca de compostos.

Mini Projecte – Calculadora de descriptors des d'un CSV

Construeix un script que:

  • Llegeixi un fitxer CSV amb una columna SMILES i una altra ID.
  • Calculi per a cada molècula: MW, LogP, HBA, HBD, enllaços rotables (ROTB) i àrea de superfície polar (TPSA) si és possible.
  • Generi un nou fitxer CSV amb les columnes originals més els descriptors calculats.
  • Utilitzi RDKit sempre que estigui disponible; si no, implementi estimacions bàsiques a partir de patrons simples.
  • Mostri un resum amb la mitjana i desviació de cada descriptor i un gràfic de dispersió MW vs LogP.