Mostrando entradas con la etiqueta python. Mostrar todas las entradas
Mostrando entradas con la etiqueta python. Mostrar todas las entradas

26 de febrero de 2024

Cómo modelar proteínas con colabfold en tu GPU local

Hola,

hoy explicaré cómo he configurado ColabFold para ejecutarlo en hardware local, en concreto en una máquina con Ubuntu 20.04 que tiene una CPU Xeon CascadeLake Silver 4210R y una tarjeta gráfica NVIDIA RTX 3090. Puedes leer más sobre AlphaFold y ColabFold aquí o en este vídeo.

1) Necesité actualizar cuda, en concreto con la versión 11.8, algo que hice como se explica aquí:

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt update
sudo apt install cuda-toolkit-11-8

2) Tras reinicar, actualicé la variable de ambiente $PATH añadiendo estas líneas a mi fichero .bashrc:

export PATH=/usr/local/cuda/bin:$PATH

export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

3) Seguí las instrucciones para Linux en https://github.com/YoshitakaMo/localcolabfold?tab=readme-ov-file#for-linux . En mi caso tardó unos pocos minutos y sumó 15G al disco duro. 

4) Probé que todo funciona con un fichero FASTA qee contiene varias secuencias, guardando los resultados en la carpeta multi/ :

colabfold_batch test.multi.faa multi/


Ahora resumo los resultados que obtuve:

  • Por defecto colabfold_batch se conecta a https://api.colabfold.com para hacer búsquedas de secuencias similares y construir alineamientos múltiples (MSA) en un formato similar a FASTA que se llama a3m. Por tanto esa parte del trabajo no se hace localmente y tendrás que usarla con medida. Si quieres saber qué versión de las bases de datos de secuencias de ColabFold estás usando puedes consultar https://github.com/sokrypton/ColabFold/wiki/MSA-Server-Database-History
  • Las primeras secuencias que usé para construir modelos en formato PDB tenían entre 114 y 162 resíduos y tardaban un par de minutos, pego aquí el log: 
  • 2024-02-26 13:05:56,639 Running colabfold 1.5.5 (d36504fad856a0e1df511c5b0434957707030319)
    2024-02-26 13:05:56,862 Running on GPU
    2024-02-26 13:05:57,354 Found 5 citations for tools or databases
    2024-02-26 13:05:57,355 Query 1/29: test1 (length 114)
    2024-02-26 13:05:58,348 Sleeping for 6s. Reason: PENDING
    2024-02-26 13:06:05,308 Sleeping for 10s. Reason: RUNNING
    2024-02-26 13:06:30,822 Padding length to 124
    2024-02-26 13:06:58,791 alphafold2_ptm_model_1_seed_000 recycle=0 pLDDT=67.9 pTM=0.31
    2024-02-26 13:07:00,321 alphafold2_ptm_model_1_seed_000 recycle=1 pLDDT=68.8 pTM=0.329 tol=9.09
    2024-02-26 13:07:01,845 alphafold2_ptm_model_1_seed_000 recycle=2 pLDDT=69.7 pTM=0.358 tol=2.28
    2024-02-26 13:07:03,373 alphafold2_ptm_model_1_seed_000 recycle=3 pLDDT=69.8 pTM=0.367 tol=3.04
    2024-02-26 13:07:03,374 alphafold2_ptm_model_1_seed_000 took 32.6s (3 recycles)
    2024-02-26 13:07:04,871 alphafold2_ptm_model_2_seed_000 recycle=0 pLDDT=71.2 pTM=0.308
    2024-02-26 13:07:06,323 alphafold2_ptm_model_2_seed_000 recycle=1 pLDDT=71.6 pTM=0.346 tol=2.14
    2024-02-26 13:07:07,848 alphafold2_ptm_model_2_seed_000 recycle=2 pLDDT=71.7 pTM=0.358 tol=2.38
    2024-02-26 13:07:09,345 alphafold2_ptm_model_2_seed_000 recycle=3 pLDDT=71.8 pTM=0.365 tol=1.31
    2024-02-26 13:07:09,346 alphafold2_ptm_model_2_seed_000 took 5.9s (3 recycles)
    2024-02-26 13:07:10,984 alphafold2_ptm_model_3_seed_000 recycle=0 pLDDT=68.1 pTM=0.298
    2024-02-26 13:07:12,529 alphafold2_ptm_model_3_seed_000 recycle=1 pLDDT=68.6 pTM=0.34 tol=4.11
    2024-02-26 13:07:13,992 alphafold2_ptm_model_3_seed_000 recycle=2 pLDDT=69.2 pTM=0.36 tol=2.49
    2024-02-26 13:07:15,484 alphafold2_ptm_model_3_seed_000 recycle=3 pLDDT=68.8 pTM=0.367 tol=1.67
    2024-02-26 13:07:15,485 alphafold2_ptm_model_3_seed_000 took 6.1s (3 recycles)
    2024-02-26 13:07:16,987 alphafold2_ptm_model_4_seed_000 recycle=0 pLDDT=66.1 pTM=0.289
    2024-02-26 13:07:18,435 alphafold2_ptm_model_4_seed_000 recycle=1 pLDDT=66.8 pTM=0.283 tol=5.61
    2024-02-26 13:07:19,933 alphafold2_ptm_model_4_seed_000 recycle=2 pLDDT=67.7 pTM=0.298 tol=1.03
    2024-02-26 13:07:21,444 alphafold2_ptm_model_4_seed_000 recycle=3 pLDDT=67.9 pTM=0.318 tol=2.04
    2024-02-26 13:07:21,445 alphafold2_ptm_model_4_seed_000 took 5.9s (3 recycles)
    2024-02-26 13:07:22,931 alphafold2_ptm_model_5_seed_000 recycle=0 pLDDT=66.8 pTM=0.322
    2024-02-26 13:07:24,403 alphafold2_ptm_model_5_seed_000 recycle=1 pLDDT=68.2 pTM=0.345 tol=9.46
    2024-02-26 13:07:25,860 alphafold2_ptm_model_5_seed_000 recycle=2 pLDDT=68.8 pTM=0.354 tol=2.3
    2024-02-26 13:07:27,342 alphafold2_ptm_model_5_seed_000 recycle=3 pLDDT=69.4 pTM=0.358 tol=1.58
    2024-02-26 13:07:27,342 alphafold2_ptm_model_5_seed_000 took 5.9s (3 recycles)
    2024-02-26 13:07:27,369 reranking models by 'plddt' metric
    2024-02-26 13:07:27,369 rank_001_alphafold2_ptm_model_2_seed_000 pLDDT=71.8 pTM=0.365
    2024-02-26 13:07:27,369 rank_002_alphafold2_ptm_model_1_seed_000 pLDDT=69.8 pTM=0.367
    2024-02-26 13:07:27,370 rank_003_alphafold2_ptm_model_5_seed_000 pLDDT=69.4 pTM=0.358
    2024-02-26 13:07:27,370 rank_004_alphafold2_ptm_model_3_seed_000 pLDDT=68.8 pTM=0.367
    2024-02-26 13:07:27,370 rank_005_alphafold2_ptm_model_4_seed_000 pLDDT=67.9 pTM=0.318
    2024-02-26 13:07:28,679 Query 2/29: test2 (length 120)
    2024-02-26 13:07:29,695 Sleeping for 9s. Reason: PENDING
    2024-02-26 13:07:39,667 Sleeping for 9s. Reason: PENDING
    2024-02-26 13:07:49,628 Sleeping for 6s. Reason: PENDING
    2024-02-26 13:07:56,610 Sleeping for 6s. Reason: PENDING
    2024-02-26 13:08:03,608 Sleeping for 5s. Reason: PENDING
    2024-02-26 13:08:09,564 Sleeping for 6s. Reason: PENDING
    2024-02-26 13:08:16,534 Sleeping for 7s. Reason: PENDING
    2024-02-26 13:08:24,518 Sleeping for 5s. Reason: PENDING
    2024-02-26 13:08:30,471 Sleeping for 7s. Reason: PENDING
    2024-02-26 13:08:38,498 Sleeping for 5s. Reason: PENDING
    2024-02-26 13:08:44,459 Sleeping for 6s. Reason: PENDING
    2024-02-26 13:08:51,412 Sleeping for 9s. Reason: PENDING
    2024-02-26 13:09:01,412 Sleeping for 9s. Reason: PENDING
    2024-02-26 13:09:11,370 Sleeping for 8s. Reason: PENDING
    2024-02-26 13:09:20,337 Sleeping for 8s. Reason: PENDING
    2024-02-26 13:09:29,316 Sleeping for 6s. Reason: RUNNING
    2024-02-26 13:09:39,703 Padding length to 124
    2024-02-26 13:09:41,194 alphafold2_ptm_model_1_seed_000 recycle=0 pLDDT=73.9 pTM=0.55
    2024-02-26 13:09:42,664 alphafold2_ptm_model_1_seed_000 recycle=1 pLDDT=73.8 pTM=0.549 tol=3.08
    2024-02-26 13:09:44,110 alphafold2_ptm_model_1_seed_000 recycle=2 pLDDT=73.6 pTM=0.549 tol=1.59
    2024-02-26 13:09:45,593 alphafold2_ptm_model_1_seed_000 recycle=3 pLDDT=74.4 pTM=0.555 tol=1.67
    2024-02-26 13:09:45,593 alphafold2_ptm_model_1_seed_000 took 5.9s (3 recycles)
    2024-02-26 13:09:47,073 alphafold2_ptm_model_2_seed_000 recycle=0 pLDDT=76.7 pTM=0.565
    2024-02-26 13:09:48,523 alphafold2_ptm_model_2_seed_000 recycle=1 pLDDT=77.1 pTM=0.57 tol=0.571
    2024-02-26 13:09:49,977 alphafold2_ptm_model_2_seed_000 recycle=2 pLDDT=76.7 pTM=0.569 tol=0.958
    2024-02-26 13:09:51,421 alphafold2_ptm_model_2_seed_000 recycle=3 pLDDT=76.9 pTM=0.572 tol=0.881
    2024-02-26 13:09:51,421 alphafold2_ptm_model_2_seed_000 took 5.8s (3 recycles)
    2024-02-26 13:09:52,877 alphafold2_ptm_model_3_seed_000 recycle=0 pLDDT=75.6 pTM=0.542
    2024-02-26 13:09:54,315 alphafold2_ptm_model_3_seed_000 recycle=1 pLDDT=75.9 pTM=0.548 tol=1.52
    2024-02-26 13:09:55,763 alphafold2_ptm_model_3_seed_000 recycle=2 pLDDT=75.9 pTM=0.552 tol=1.69
    2024-02-26 13:09:57,218 alphafold2_ptm_model_3_seed_000 recycle=3 pLDDT=75.8 pTM=0.555 tol=0.883
    2024-02-26 13:09:57,219 alphafold2_ptm_model_3_seed_000 took 5.8s (3 recycles)
    2024-02-26 13:09:58,705 alphafold2_ptm_model_4_seed_000 recycle=0 pLDDT=73.9 pTM=0.56
    2024-02-26 13:10:00,177 alphafold2_ptm_model_4_seed_000 recycle=1 pLDDT=75.1 pTM=0.57 tol=2.2
    2024-02-26 13:10:01,620 alphafold2_ptm_model_4_seed_000 recycle=2 pLDDT=75.4 pTM=0.571 tol=1.78
    2024-02-26 13:10:03,076 alphafold2_ptm_model_4_seed_000 recycle=3 pLDDT=75.7 pTM=0.575 tol=2.04
    2024-02-26 13:10:03,077 alphafold2_ptm_model_4_seed_000 took 5.8s (3 recycles)
    2024-02-26 13:10:04,572 alphafold2_ptm_model_5_seed_000 recycle=0 pLDDT=75.2 pTM=0.573
    2024-02-26 13:10:06,026 alphafold2_ptm_model_5_seed_000 recycle=1 pLDDT=76.2 pTM=0.585 tol=2.12
    2024-02-26 13:10:07,498 alphafold2_ptm_model_5_seed_000 recycle=2 pLDDT=76.2 pTM=0.587 tol=1.44
    2024-02-26 13:10:08,958 alphafold2_ptm_model_5_seed_000 recycle=3 pLDDT=76.6 pTM=0.589 tol=1.21
    2024-02-26 13:10:08,959 alphafold2_ptm_model_5_seed_000 took 5.9s (3 recycles)
    2024-02-26 13:10:08,986 reranking models by 'plddt' metric
    2024-02-26 13:10:08,987 rank_001_alphafold2_ptm_model_2_seed_000 pLDDT=76.9 pTM=0.572
    2024-02-26 13:10:08,987 rank_002_alphafold2_ptm_model_5_seed_000 pLDDT=76.6 pTM=0.589
    2024-02-26 13:10:08,987 rank_003_alphafold2_ptm_model_3_seed_000 pLDDT=75.8 pTM=0.555
    2024-02-26 13:10:08,987 rank_004_alphafold2_ptm_model_4_seed_000 pLDDT=75.7 pTM=0.575
    2024-02-26 13:10:08,987 rank_005_alphafold2_ptm_model_1_seed_000 pLDDT=74.4 pTM=0.555
    2024-02-26 13:10:10,274 Query 3/29: test3 (length 162)
    2024-02-26 13:10:11,241 Sleeping for 8s. Reason: PENDING
    2024-02-26 13:10:20,230 Sleeping for 10s. Reason: PENDING
    2024-02-26 13:10:31,195 Sleeping for 5s. Reason: RUNNING
    2024-02-26 13:10:37,194 Sleeping for 6s. Reason: RUNNING
    2024-02-26 13:10:44,153 Sleeping for 9s. Reason: RUNNING
    2024-02-26 13:10:54,142 Sleeping for 10s. Reason: RUNNING
    2024-02-26 13:11:05,109 Sleeping for 8s. Reason: RUNNING
    2024-02-26 13:11:14,082 Sleeping for 6s. Reason: RUNNING
    2024-02-26 13:11:21,030 Sleeping for 8s. Reason: RUNNING
    2024-02-26 13:11:30,005 Sleeping for 9s. Reason: RUNNING
    2024-02-26 13:11:39,984 Sleeping for 7s. Reason: RUNNING
    2024-02-26 13:11:47,941 Sleeping for 10s. Reason: RUNNING
    2024-02-26 13:11:58,903 Sleeping for 9s. Reason: RUNNING
    2024-02-26 13:12:08,881 Sleeping for 5s. Reason: RUNNING
    2024-02-26 13:12:14,891 Sleeping for 9s. Reason: RUNNING
    2024-02-26 13:12:32,470 Padding length to 172
    2024-02-26 13:13:00,100 alphafold2_ptm_model_1_seed_000 recycle=0 pLDDT=62.9 pTM=0.433
    2024-02-26 13:13:02,186 alphafold2_ptm_model_1_seed_000 recycle=1 pLDDT=63.4 pTM=0.433 tol=8.27
    2024-02-26 13:13:04,282 alphafold2_ptm_model_1_seed_000 recycle=2 pLDDT=64.1 pTM=0.431 tol=8.02
    2024-02-26 13:13:06,403 alphafold2_ptm_model_1_seed_000 recycle=3 pLDDT=63.8 pTM=0.427 tol=8.51
    2024-02-26 13:13:06,404 alphafold2_ptm_model_1_seed_000 took 33.9s (3 recycles)
    2024-02-26 13:13:08,535 alphafold2_ptm_model_2_seed_000 recycle=0 pLDDT=60.2 pTM=0.417
    2024-02-26 13:13:10,637 alphafold2_ptm_model_2_seed_000 recycle=1 pLDDT=61 pTM=0.423 tol=6.09
    2024-02-26 13:13:12,742 alphafold2_ptm_model_2_seed_000 recycle=2 pLDDT=61.4 pTM=0.428 tol=3.33
    2024-02-26 13:13:14,846 alphafold2_ptm_model_2_seed_000 recycle=3 pLDDT=61.2 pTM=0.425 tol=1.8
    2024-02-26 13:13:14,846 alphafold2_ptm_model_2_seed_000 took 8.4s (3 recycles)
    2024-02-26 13:13:16,979 alphafold2_ptm_model_3_seed_000 recycle=0 pLDDT=62 pTM=0.425
    2024-02-26 13:13:19,099 alphafold2_ptm_model_3_seed_000 recycle=1 pLDDT=62.3 pTM=0.43 tol=7.21
    2024-02-26 13:13:21,197 alphafold2_ptm_model_3_seed_000 recycle=2 pLDDT=61.9 pTM=0.426 tol=4.32
    2024-02-26 13:13:23,303 alphafold2_ptm_model_3_seed_000 recycle=3 pLDDT=62.1 pTM=0.427 tol=5.17
    2024-02-26 13:13:23,304 alphafold2_ptm_model_3_seed_000 took 8.4s (3 recycles)
    2024-02-26 13:13:25,461 alphafold2_ptm_model_4_seed_000 recycle=0 pLDDT=60.5 pTM=0.418
    2024-02-26 13:13:27,552 alphafold2_ptm_model_4_seed_000 recycle=1 pLDDT=60.8 pTM=0.417 tol=9.52
    2024-02-26 13:13:29,658 alphafold2_ptm_model_4_seed_000 recycle=2 pLDDT=60.3 pTM=0.41 tol=9.23
    2024-02-26 13:13:31,749 alphafold2_ptm_model_4_seed_000 recycle=3 pLDDT=60.5 pTM=0.411 tol=6.08
    2024-02-26 13:13:31,750 alphafold2_ptm_model_4_seed_000 took 8.4s (3 recycles)
    2024-02-26 13:13:33,905 alphafold2_ptm_model_5_seed_000 recycle=0 pLDDT=59.9 pTM=0.416
    2024-02-26 13:13:36,038 alphafold2_ptm_model_5_seed_000 recycle=1 pLDDT=60.1 pTM=0.415 tol=9.96
    2024-02-26 13:13:38,154 alphafold2_ptm_model_5_seed_000 recycle=2 pLDDT=59.7 pTM=0.409 tol=3.89
    2024-02-26 13:13:40,252 alphafold2_ptm_model_5_seed_000 recycle=3 pLDDT=59.4 pTM=0.415 tol=11.4
    2024-02-26 13:13:40,253 alphafold2_ptm_model_5_seed_000 took 8.5s (3 recycles)
    2024-02-26 13:13:40,294 reranking models by 'plddt' metric
    2024-02-26 13:13:40,294 rank_001_alphafold2_ptm_model_1_seed_000 pLDDT=63.8 pTM=0.427
    2024-02-26 13:13:40,294 rank_002_alphafold2_ptm_model_3_seed_000 pLDDT=62.1 pTM=0.427
    2024-02-26 13:13:40,294 rank_003_alphafold2_ptm_model_2_seed_000 pLDDT=61.2 pTM=0.425
    2024-02-26 13:13:40,295 rank_004_alphafold2_ptm_model_4_seed_000 pLDDT=60.5 pTM=0.411
    2024-02-26 13:13:40,295 rank_005_alphafold2_ptm_model_5_seed_000 pLDDT=59.4 pTM=0.415
  • Como ves el propio script espera cuando el servidor remoto está ocupado.
  • Para cada secuencia problema obtienes figuras como éstas:




Hasta pronto,

Bruno

PD Cuando acabes de instalar deberías tener algo similar en tu fichero $HOME/.bashrc:

export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
export PATH="$HOME/colabfold/colabfold-conda/bin:$PATH"

Cuando no vayas a usar colabfold comenta estas líneas para usar perl y python del sistema

PD2 Me comentan colegas de ULiverpool que haciendo 800-900 MSAs al día en https://api.colabfold.com no han tenido problemas 

PD3 Si no reconoce tu GPU mira posibles soluciones en https://github.com/YoshitakaMo/localcolabfold/issues/210

PD4: Puedes bloquear la versión de CUDA que hayas instalado cono alfo como:

 sudo apt-mark hold cuda-toolkit-11-8


25 de abril de 2023

Por qué Perl?

De vez en cuando en este blog toca escribir sobre Perl, uno de los lenguajes que usamos en nuestro trabajo, en mi caso el que más uso la verdad.

Voy a traducir y resumir https://two-wrongs.com/why-perl , porque creo que plasma mi experiencia bastante bien [en negrita mis comentarios]:

"A veces me preguntan porqué uso tanto el Perl. No soy acaso fan de los lenguajes fuertemente tipados? Sí. Pídeme que escriba algo que sepa a ciencia cierta que se convertirá en un gran sistema y elegiré un lenguaje fuertemente tipado sin duda [...]. Pero la mayor parte de lo que escribo nunca se convertirá en un gran sistema. Esto es lo que Perl hace bien:

  1. Está instalado por defecto en todas partes y no necesito ser superusuario para ejecutarlo.
  2. Con mucha disciplina, los scripts Perl pueden escalar hasta construir sistemas grandes y complejos.
  3. Sé que un script Perl que escriba hoy funcionará sin cambios en 10 años, sobre todo si me limito a importar módulos core.
  4. Perl puede reemplazar en la práctica a cualquier lenguaje shell, aunque combina muy bien con bucles bash.
  5. Perl tiene una sintaxis core relativamente pequeña, flexible y extensible. 

Estos requerimientos están ordenados por prioridad, siendo el primero el más importante. Cuando quiero hacer un prototipo rápidamente no quiero que mi primera tarea sea 'Primero instala el ambiente ...'. Como los prototipos suelen usarse más allá de lo que inicialmente pensamos, es importante que sea posible escribir software en ese lenguaje que se pueda mantener y que funcione mientras haya personas interesadas en usarlo.

Perl es único en cuanto a estas condiciones. La siguiente tabla resume otras alternativas que he probado al menos un mes, donde los asteriscos marcan condiciones que se cumplen de manera incompleta:

"
 

En general estoy bastante de acuerdo con esta carta de presentación del lenguaje. Creo que el principal problema de Perl es que su extrema flexibilidad permite escribir programas que pueden ser difíciles de leer por otros, queda en tu mano documentar y estructurar bien el código para que eso no ocurra,

Bruno

 


15 de junio de 2021

entornos Python con pyenv

Hola,

si programas en Python o usas software escrito en este lenguaje es posible que te hayas enfrentado a la necesidad de usar una versión concreta que no tienes instalada en tu sistema, por ejemplo la versión 3.7.9. En esta entrada explico una manera de resolver este problema en Linux con ayuda de pyenv, que de hecho te permite tener múltiples versiones en paralelo, cada una con su propio espacio de dependencias. Espero que aquí quede más claro que en esta otra entrada.

Lo primero que necesitas es una partición en tu disco para pyenv:  

export PYENV_ROOT="/mi/particion/.pyenv"

curl https://pyenv.run | bash
  
# install python 3.7.9 (EOF June 2023)
pyenv install 3.7.9


Si todo va bien ahora debes añadir las siguientes líneas al final de tu fichero .bashrc:

if [[ -d "/mi/particion/.pyenv" ]]; then
    export PYENV_ROOT="/mi/particion/.pyenv"
    export PATH="$PYENV_ROOT/bin:$PATH"
    eval "$(pyenv init --path)"
    eval "$(pyenv virtualenv-init -)"
fi

 

Ahora ya puedes crear un entorno virtual sobre esta versión de Python, por ejemplo 'proyectox', e instalar dependencias específicas de ese proyecto:

pyenv virtualenv 3.7.9 proyectox
pyenv local proyectox
pip install --upgrade pip
 
# dependencias, tras clonar https://github.com/proyextox (ejemplo, no existe)
pip install -r proyectox/requirements.txt


Finalmente, ya puedes trabajar dentro de ese entorno:

pyenv local proyectox



Hasta pronto,

Bruno

4 de noviembre de 2020

Course on scripting with the Linux shell

 Hi,  Carlos Cantalapiedra and me recently put together teaching material about scripting in the linux terminal.

The material can be found at repository https://github.com/eead-csic-compbio/scripting_linux_shell 

There are five sessions and the goal is for you to learn the basics of the Linux shell and scripting for data sciences such as genomics and plant breeding:

session title required time URL
0 Setup prior to course session 0
1 Linux basics and files 2h session 1
2 Processes and scripts 2h session 2
3 Parsing with regular expressions 2h session 3
4 Perl one-liners 2h session 4
5 Advanced scripts 2h session 5 


Figure of the standard streams, taken from https://en.wikipedia.org/wiki/Standard_streams

 

If you spot errors please send pull requests, hope this helps some of you out there,

Bruno 

PD si prefieres aprender en español echa un vistazo a https://github.com/vinuesa/intro2linux


































6 de junio de 2020

Entrenando una red neuronal keras en linux

Hola,
tras la última entrada creo que ha llegado el momento de comenzar a programar redes neuronales profundas con la ayuda del libro Deep Learning Illustrated. En este caso el autor ha programado sus ejemplos en python, uno de los lenguajes más utilizados en este campo, y por tanto deberás crearte un ecosistema adecuado con todas las herramientas y dependencias necesarias, en este caso tensorflow y su interfaz keras. En un sistema CentOS Linux lo hice de la siguiente manera, con pyenv:
sudo curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

# agrego pyenv a .bashrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

# instalo python 3.6 y actualizo pip
pyenv install 3.6.0
pyenv local 3.6.0
pip install --upgrade pip
pip install jupyter
# creo un ecosistema/virtualenv al que llamo DL
pyenv virtualenv 3.6.0 DL
pyenv shell DL
# instalo las dependencias del libro de Jon Krohn
# en mi caso tuve que poner TMPDIR=/particion_grande/ antes de pip
# porque se llenaba la particion /tmp
pip install tensorflow
pip install keras

# otra librería de aprendizaje prodfundo alternativa a keras & tensorflow
pip install mxnet

Y ya está, ahora cuando quiero usar este ecosistema  solamente tengo que hacer:
$ pyenv shell DL
Todos los ejemplos de libro están disponibles en https://github.com/the-deep-learners/deep-learning-illustrated, en forma de cuadernos jupyter que puedes explorar directamente desde GitHub o en tu navegador. Si quieres probarlos directamente en el terminal deberás convertirlos a scripts .py y luego ejecutarlos:
jupyter nbconvert --to script deep-learning-illustrated/notebooks/regression_in_keras.ipynb
python deep-learning-illustrated/notebooks/regression_in_keras.py
En este caso obtendremos la siguiente salida, que resume la arquitectura de la red especificada en regression_in_keras.ipynb y su entrenamiento a lo largo de 32 épocas:

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_1 (Dense)              (None, 32)                448
_________________________________________________________________
batch_normalization_1 (Batch (None, 32)                128
_________________________________________________________________
dense_2 (Dense)              (None, 16)                528
_________________________________________________________________
batch_normalization_2 (Batch (None, 16)                64
_________________________________________________________________
dropout_1 (Dropout)          (None, 16)                0
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 17
=================================================================
Total params: 1,185
Trainable params: 1,089
Non-trainable params: 96

Train on 404 samples, validate on 102 samples
Epoch 1/32

  8/404 [..............................] - ETA: 30s - loss: 865.3292
 80/404 [====>.........................] - ETA: 2s - loss: 720.8563
152/404 [==========>...................] - ETA: 1s - loss: 644.4068
232/404 [================>.............] - ETA: 0s - loss: 602.0502
304/404 [=====================>........] - ETA: 0s - loss: 578.7887
376/404 [==========================>...] - ETA: 0s - loss: 588.8638
404/404 [==============================] - 1s 2ms/step - loss: 583.1135 - val_loss: 786.3666
....

  8/404 [..............................] - ETA: 0s - loss: 18.8216
 88/404 [=====>........................] - ETA: 0s - loss: 34.8777
168/404 [===========>..................] - ETA: 0s - loss: 37.6842
248/404 [=================>............] - ETA: 0s - loss: 48.3836
328/404 [=======================>......] - ETA: 0s - loss: 45.0179
404/404 [==============================] - 0s 761us/step - loss: 43.5160 - val_loss: 133.9931

Hasta pronto,
Bruno

15 de diciembre de 2016

Chuleta de Python 3 para principiantes

Hoy quiero compartir con vosotros una chuleta de Python 3 que he creado para mis estudiantes, he intentado recopilar en dos caras de DIN-A4 los tipos de datos, operadores, métodos, funciones y otros contenidos útiles que uno necesita tener a mano cuando comienza a programar en Python 3 (incluso meses más tarde).

Puedes descargarte la chuleta en formato PDF de mi blog en inglés o usarla online:



13 de mayo de 2015

Curso de Python para biólogos - Lección 7. Lectura y escritura de archivos

Con Python podemos leer, crear y modificar archivos de texto. Por ejemplo podemos leer un fichero con miles/millones de secuencias de DNA y extraer información del mismo, lo cual sería muy complicado de forma manual. Se verá un ejemplo al final de la lección.

Trabajando con directorios

Antes de empezar a crear y leer archivos, vamos a consultar el directorio de trabajo por defecto de Python con el comando 'os.getcwd', crear un nuevo directorio para trabajar en esta lección con 'os.makedirs' y cambiar el directorio de trabajo por este nuevo directorio ('os.chdir'). Para realizar todo ello primero tenemos que importar el módulo 'import os' (Operating System) que nos proporcionará los métodos mencionados. Un módulo es una extensión de Python y se debe importar para poder trabajar con sus herramientas.

Creación de archivos

Una vez que estamos en el directorio de trabajo deseado, vamos a crear un archivo llamado 'example.txt', para ello usaremos la función 'open' con la opción 'w' que indica escritura (write). El nuevo archivo será un objeto guardado en la variable 'f' y con el método 'write' podremos insertar un texto en el mismo. No debemos olvidar cerrar siempre el archivo después de leer o modificar sus contenidos con el método 'close'. Si abrimos el archivo con nuestro explorador de archivos, veremos el texto que contiene.

Usando un bucle 'for' podemos insertar automáticamente múltiples líneas de texto:

Lectura de archivos

Para leer un archivo, primero debemos abrirlo con la función 'open' y la opción 'r' que indica lectura (read). El método 'read' leerá todo el archivo de una vez si no se especifica ningún argumento. Importante, después de leerlo debemos cerrarlo con la función close.

Una  forma más adecuada de leer un fichero puede ser línea a línea con un bucle 'for', cada línea será almacenada en la variable 'line' en cada iteración.

Existen varias formas alternativas de leer los ficheros, entre ellas los métodos 'read' y 'readline', ambos aceptan especificar el número de caracteres que serán leídos. En próximas lecturas, Python continuará en la posición que terminó la anterior.

Ejercicio. Contar el número de genes codificantes que tiene el genoma de Escherichia coli

Para ello, primero descargaremos el fichero del proteoma de E. coli del siguiente enlace. Después, copiaremos el fichero descargado a nuestro directorio de trabajo. Y por último escribiremos un código en Python que cuente el número de veces que aparece el símbolo '>' al comienzo de una línea, dicho símbolo indica el comienzo de una proteína.

Si hemos hecho todo bien, el número de genes debería ser '4140', o similar (las nuevas versiones del genoma pueden variar ligeramente dicho número). Podemos confirmarlo en la web de KEGG.

Próxima lección

 En la próxima lección se hará una introducción a las expresiones regulares.

Curso de Python para biólogos - Lección 6. Bucles 'for'

En la lección de hoy presentaremos los bucles 'for', muy similares a los 'while' explicados en la lección 4, pero con un código más sencillo.

Bucles 'for':

Un bucle 'for', al igual que 'while', repite la ejecución de un bloque de código un número determinado de veces. Si invocamos el bucle 'for' con un nombre de variable más 'in' y una lista, el número de repeticiones vendrá determinado por el número de elementos de la lista, que serán pasados de uno en uno a la variable durante cada iteración. Veamos algunos ejemplos:

Con la función 'range' podemos especificar un listado de números que serán pasados a la variable especificada en el bucle. El primer parámetro de la función será el número inicial en el bucle, el segundo parámetro indicará el último número y el tercer parámetro proporcina el incremento a aplicar en cada iteración, por defecto el incremento es 1.

Como ya se ha comentado 'for' es una simplificación de 'while' cuando se trabaja con listas o números. El mismo código con 'while' es posible, pero será más largo y complejo.

Veamos como podemos usar 2 bucles 'for' anidados para recorrer los elementos de una matriz:

Sentencias de control de bucles: 'break', 'continue' y 'pass'

A veces nos interesará salir de un bucle (ya sea 'while' o 'for') antes de terminar todas las iteraciones, la forma de conseguirlo es mediante las sentencias de control 'break' y 'continue'. 'Break' terminará totalmente el bucle y continuará la ejecución del código del resto de programa. 'Continue' terminará la ejecución de una iteración y pasará directamente a la siguiente iteración del bucle, sin salir del bucle. 'Pass' no hace nada, es simplemente una sentencia que puede ser usada cuando no se requiere ejecutar ninguna acción pero es requerido escribir algo.

Bucles 'for' y diccionarios:

Los bucles 'for' también pueden ser útiles para procesar una a una las claves de un diccionario, sus valores o ambas cosas a la vez.


Ejercicios: 

Volvamos a los ejercicios propuestos en la lección anterior y resueltos con bucles 'while', veamos cómo pueden resolverse de una forma más sencilla mediante bucles 'for'.



Próxima lección

En la próxima lección se explicará como leer y escribir archivos con Python.



23 de marzo de 2015

Curso de Python para biólogos - Lección 5. Funciones y ejercicios prácticos

Hoy descansaremos un poco y sólo explicaremos un nuevo concepto teórico, pero muy importante, las funciones en Python. Tras ello se propondrán varios ejercicios para aplicar los conocimientos adquiridos en las lecciones previas (1, 2, 3 y 4).

Funciones en Python

Una función es un bloque de código que toma ciertos datos o variables como argumentos y devuelve otros datos o variables como resultado. Aunque no nos hayamos dado cuenta, ya hemos usado funciones anteriormente: print(), input(), int(), str(), len(), type(), min(), max()...dichas funciones vienen por defecto con Python y alguien las ha escrito previamente para que nosotros las podamos usar. La importancia fundamental de las funciones es que nos permiten escribir un código una sola vez y utilizarlo todas las veces que sea necesario sin volver a escribirlo, lo cual nos ahorra tiempo y simplifica los programas.

Las funciones se especifican con 'def' seguido del nombre de la función y entre paréntesis tantas variables como argumentos utiliza, estas variables guardarán los argumentos que demos al llamar a la función. No hay que olvidar los dos puntos al final de esta primera línea y escribir el bloque de código de la función tabulado (4 espacios). Al final de la función el resultado de la misma se devuelve con el comando 'return'. Para ejecutar o llamar una función simplemente hay que escribir su nombre y entre paréntesis sus argumentos. El resultado/s de las funciones los podemos guardar en variables o usarlos directamente.

Veamos en el primer ejemplo cómo escribir una función que realiza la suma de dos números y la devuelve como resultado. En el segundo ejemplo, la función recibe un nombre y devuelve una frase dando la bienvenida.

Ejercicio 1: Calcular el factorial de un número

El factorial de un número se define como el producto de todos los números enteros positivos desde 1. El ejercicio propuesto consiste en escribir una función que lo calcule usando un bucle 'while' que vaya restando (o sumando) número a número y guardando el resultado de la multiplicación por el anterior. No vale mirar en Google y usar funciones ya escritas.

Ejercicio 2: Contar el número de nucleótidos en una secuencia de DNA

Ahora escribiremos una función que cuente el número de pares de bases de una secuencia de DNA tomada como argumento de la función. Creo que este problema será más sencillo que el anterior, el código de la función puede ocupar tan sólo una línea, pero sugiero utilizar el bucle 'while' para leer letra a letra y aprender más.

Ejercicio 3: Encontrar un codón de inicio de la traducción en una secuencia de DNA

El ejercicio consiste en encontrar el codón de inicio de la traducción, osea la palabra 'ATG', en una secuencia de DNA. La función puede ser muy sencilla utilizando expresiones regulares, pero como no las hemos estudiado todavía, propongo reutilizar el código del Ejercicio 2 que debería leer letra a letra la secuencia e ir extrayendo palabras de 3 letras en cada iteración del bucle. Comprobar si la palabra es 'ATG' con una sentencia condicional, si lo es retornar la posición como resultado de la función, y si no seguir hasta terminar de leer toda la secuencia.

Ejercicio 4: Calculando una secuencia consenso

El último ejercicio de hoy consiste en escribir una función que tome como argumentos 3 secuencias de DNA (preferiblemente de la misma longitud, para evitar problemas y errores, si no calcular el consenso hasta la longitud de la secuencia más corta) y devuelva una única secuencia que contenga en cada posición el nucleótido más frecuente o en su defecto la letra 'N'. Este ejercicio es el más complejo y requiere utilizar bucles 'while', sentencias condicionales...


Buena suerte y nos vemos en la próxima lección.

19 de marzo de 2015

Curso de Python para biólogos - Lección 4. Entrada de datos y bucles while

En esta nueva lección aprenderemos a pedir datos al usuario desde nuestro programa y a realizar nuestros primeros bucles. Como veremos, un bucle consiste en repetir un bloque de código varias veces sin tener que volver a escribirlo.

Entrada de datos desde la línea de comandos

A veces necesitaremos introducir datos en nuestro programa de forma interactiva, lo que significa que preguntaremos o pediremos al usuario cierta información (por ej. linux siempre nos pregunta antes de instalar un nuevo programa y debemos responder 'yes' o 'no'). En Python se utiliza la función 'input', dicha función devuelve el texto introducido por el usuario antes de pulsar Enter. El texto tendrá formato de cadena (string), por lo que no podrá ser utilizado directamente en caso de ser un número, habrá que convertir la cadena en número.

Conversión entre diferentes formatos de datos

Muchas funciones y métodos de Python sólo aceptan un tipo de datos, por ejemplo 'print' requiere cadenas o las operaciones aritméticas requieren números. Los tipos de datos que conocemos son: números, cadenas, listas y diccionarios. Simplificando, en Python existen 2 clases de números, los enteros (int) y los decimales (float). Por ello es importante conocer cómo convertir una cadena (devuleta por la función 'input' por ejemplo) en un número antes de realizar operaciones aritméticas, o convertir un número en una cadena antes de imprimirlo.
Si intentamos elevar al cuadrado un número introducido mediante 'input' nos dará error, porque antes deberemos convertir la cadena devuelta por 'input' en un tipo de número (int o float).
Si el texto devuelto por 'input' contiene decimales, al intentar convertirlo en número entero nos devolverá un error. La solución es convertirlo a decimal primero. Pero cuidado, operar con números enteros es diferente que con números decimales, y los resultados pueden variar mucho.

Validación de datos con 'try' y 'except':

Como hemos visto en los ejemplos anteriores, muchas veces tenemos errores al intentar operar con los diferentes tipos de datos. Una forma de evitar problemas es detectar los errores con la sentencia 'try:' y evitar que se ejecute el código que origina el error para ejecutar un código alternativo especificado por 'except:'. Se podría traducir cómo: "en caso de error... hacer lo siguiente...".
 Notar cómo siempre hay diferentes maneras de hacer lo mismo...
Pero 'try' y 'except' no son milagrosos, no permiten por ejemplo corregir errores en la sintaxis de nuestro código, como puede ser olvidarnos un paréntesis o unas comillas.

Bucles 'while':

Por fin vamos a adentrarnos en el fascinante mundo de los bucles. Un bucle es un bloque de código que es ejecutado varias veces, pero sólo hay que escribirlo una vez :)

La particularidad de un bucle 'while' es que es ejecutado indefinidamente (bucle infinito) mientras la condición que le sigue es cierta (True). Como en el caso de las sentencias condicionales con 'if', el código a ejecutar mientras se cumpla la condición debe ser tabulado 4 espacios para ser reconocido por Python. Veamos unos ejemplos.
Empecemos a aplicar los conocimientos adquiridos y veamos cómo usar sentencias condicionales (if...elif...else...) dentro de un bucle, la tabulación será muy importante...

Ejercicio1. Programa para adivinar un número:

Para terminar la lección haremos dos ejercicios muy interesantes. El primero será escribir un código que genera un número aleatorio entre 1 y 100, y nos preguntará sucesivante por el número hasta que lo adivinemos. Las primeras líneas (from random import randint y number=randint(1,100)) son necesarias para generar el número aleatorio guardado en la variable 'number' pero serán explicadas en próximas lecciones.
Pero, qué pasa si nos equivocamos y no escribimos un número? El programa devolverá un error a no ser que nos preparemos para ello:

Ejercicio2. Cantar una canción

En el último ejercicio de hoy, crearemos un código que nos pida escribir una canción línea a línea y después la mostrará en pantalla 2 veces, imprimiendo línea por línea con un bucle 'while'.
  
Próxima lección: bucles 'for' 




9 de marzo de 2015

Curso de Python para biólogos - Lección 3. Data comparison and conditional statements

Comenzamos la semana con una nueva lección de Python, todavía no quedan un par de lecciones de conceptos básicos antes de empezar a hacer algún pequeño programa para resolver problemas biológicos. En la presente lección explicaremos cómo se pueden comparar datos y condicionar la ejecución del código de acuerdo a dichas comparaciones.



Expresiones booleanas

Una expresión booleana es una comparación entre 2 valores o variables que devuelve un resultado de cierto (true) si ambos valores son iguales o ambas variables contienen el mismo valor y falso (false) si son diferentes. True y false son los dos únicos valores de otro tipo de datos llamado booleano (pero no queremos explicar más tipos de datos, con los ya vistos es suficiente: números, cadenas, listas y diccionarios).

Operadores de comparación y lógicos

Se denominan operadores de comparación a las expresiones mostradas en la imagen (==, !=, <, >, <= y >=), permiten realizar comparaciones de dos valores o variables con 2 únicos posibles resultados: true o false.
Los comparadores lógicos son 'and', 'or' and 'not' y permiten combinar diferences comparaciones. En la tabla se muestran los posibles resultados. 'and' da como resultado true si todas las comparaciones son ciertas y false si una de ellas es falsa. 'or' devuelve true si al menos una de las comparaciones es cierta y false si todas son falsas. 'not' cambia el resultado de una comparación de true a false o al contrario.
 Veamos unos ejemplos:

Sentencias condicionales

Una sentencia condicional decide si se ejecuta o no el código indentado que le sigue a continuación, si la comparación es cierta el código se ejecuta, si es falsa no sucede nada. Las sentencias condicionales se escriben con el operador 'if' seguido de una comparación y termina con dos puntos ':'. En las siguientes líneas se escribe el código indentado con espacios o tabulador (recomendado 4 espacios). El código indentado sólo se ejecutará si la comparación da como resultado true.
Las sentencias condicionales se pueden hacer más completas añadiendo condiciones con el operador 'elif'. Si la primera condición (con 'if') no se cumple, se pasará a comprobar si se cumple la segunda (con 'elif') y así sucesivamente hasta que se agoten las condiciones. Si todas las comparaciones con 'if' y 'elif' son falsas, entonces se ejecutará el código especificado por el operador 'else'.
Para usar las sentencias condicionales con listas, o con valores de diccionarios (recordar dict.values() devuelve una lista de los valores asociados a las claves y dict.keys() devuelve una lista de todas las claves) existe la expresión if in :. Dicha expresión permite buscar un valor en una lista y si lo encuentra ejecuta el código indentado. Es una expresión muy útil que usaremos en futuras lecciones.

Condicionales anidados

Para terminar por hoy veremos une ejemplo donde hay una combinación de comparaciones y operadores lógicos muy larga y que hace confuso el código (lo que también propicia errores al escribirlo, por ejemplo si nos dejamos un paréntesis). El mismo código se puede escribir introduciendo unas sentencias condicionales dentro de otras, el código es más largo, pero también más claro y conciso. Cada sentencia condicional que se escribe debe ser indentada, si escribimos una sentencia condicional dentro de otra deberemos indentar el doble de espacios.

Próxima lección

En la próxima lección veremos como pedir al usuario que introduzca datos y cómo realizar bucles 'while'.