Compare commits

...

3 Commits

Author SHA1 Message Date
Samuel Ortion af5651188b
Add a post on Vertex Cover and its Integer Linear Programming solution 2025-11-06 08:22:33 +01:00
Samuel Ortion 4ee5c9cf05
feat: Add translated articles links 2024-05-24 22:08:55 +02:00
Samuel Ortion 96d009ba99
Update posts
Change favicon

Add French version of tutorial on Wine for ultrasound analysis
2024-05-24 20:56:47 +02:00
36 changed files with 1224 additions and 213 deletions

View File

@ -1,5 +1,5 @@
---
baseURL: 'https://blog.samuel.ortion.fr/'
baseURL: 'https://samuel.ortion.fr/'
languageCode: en-us
title: A blog from a juvenile Geekus biologicus
theme: 'mus'
@ -9,7 +9,7 @@ params:
author: Samuel Ortion
email: samuel@ortion.fr
avatar: /images/me.png
description: ""
description: "The blog of a juvenile Geekus biologicus"
# Uncomment if you need this
# images:
# - images/og-featured.png # relative path to "static" directory
@ -70,15 +70,15 @@ params:
# suffixes:
# - "gmi"
outputFormats:
# GEMINI:
# name: GEMINI
# isPlainText: true
# isHTML: false
# mediatype: text/gemini
# protocol: "gemini://"
# permalinkable: true
# outputFormats:
# GEMINI:
# name: GEMINI
# isPlainText: true
# isHTML: false
# mediatype: text/gemini
# protocol: "gemini://"
# permalinkable: true
outputs:
home: ["HTML", "RSS", "GEMINI"]
page: ["HTML", "GEMINI"]
home: ["HTML", "RSS",] # "GEMINI"]
page: ["HTML"] #, "GEMINI"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

18
content/pages/news.org Normal file
View File

@ -0,0 +1,18 @@
#+title: News
#+author: Samuel Ortion
#+date: <2024-04-14 Sun>
#+updated: <2024-04-14 Sun>
#+draft: false
* <2025-10-01 Wed>
Je commence une thèse au Laboratoire d'Analyses Bioinformatiques pour la Génomique et le Métabolisme au Génoscope ([[https://labgem.genoscope.cns.fr/][LABGeM]]).
Je vais travailler sur une méthode de reconstruction de réseaux métaboliques à l'échelle des pangénomes de bactéries et d'archées.
* <2025-01-01 Wed>
Je commence un stage de Master 2 au LaMME, sous la direction de Carène Rizzon, Marie Szafranski et Franck Samson du LaMME et de Emmanuelle Lerat du LBBE (CNRS / Lyon). Il porte sur la prédiction de la redondance fonctionelle de paire de gènes dupliqués chez /Arabidopsis thaliana/ avec des approches de /machine learning/.
* <2024-04-15 Mon>
Je commence un stage au Laboratoire de Mathématiques et Modélisation d'Évry (LaMME), pour travailler sur un pipeline de détection de gènes dupliqués en tandem sous la supervision de Carène Rizzon et Franck Samson.

View File

View File

@ -0,0 +1,164 @@
---
title: Analyze Ultrasound on GNU/Linux using Wine
author: Samuel Ortion
date: 2021-03-25
modifdate: 2024-05-18
tags: [audio, bat, bird, ultrasound, syrinx, batsound]
lang: en
aliases: ["/analyse-sound-on-gnulinux-using-wine.html"]
slug: analyze-ultrasound-on-gnulinux-using-wine
---
After recording bats, orthoptera or birds sounds, it is often necessary to have a look at the spectrograms of the sounds, for instance while analyzing [Vigie-Chiro Program](http://www.vigienature.fr/fr/chauves-souris) bat records.
The software needed to do so are often developed only for Windows. In this article, we will learn how to install these softwares (e.g., Kaleidoscope, Syrinx, Batsound 4, 7-zip and Lupas-Rename).
## Install Wine
Wine is a software that enable .exe software to run on UNIX systems such as Linux or Mac OS.
### On Debian and derivatives (Ubuntu...)
Enable 32 bit packages (if you haven't already):
```bash
sudo dpkg --add-architecture i386
```
Download and install the repository key:
```bash
wget -nc https://dl.winehq.org/wine-builds/winehq.key
sudo apt-key add winehq.key
```
Add the repository to `/etc/apt/sources.list` or create a `wine.list` file under `/etc/apt/sources.list.d/` with the following content (recommended):
```textile
deb https://dl.winehq.org/wine-builds/debian/ buster main
```
Update packages
```bash
sudo apt update
```
Install Wine stable
```bash
sudo apt install --install-recommends winehq-stable
```
### On Fedora, RHEL, and derivatives
Add repository :
```bash
dnf config-manager --add-repo https://dl.winehq.org/wine-builds/fedora/33/winehq.repo
```
Install stable package :
```bash
dnf install winehq-stable
```
## Install Kaleidoscope
Kaleidoscope is available on both fedora and debian based distros at [wildlife acoustics](https://www.wildlifeacoustics.com/).
## Install Syrinx
As all the softwares in the following, Syrinx is not available for GNU/Linux, we need Wine to execute the `.exe`.
Syrinx-PC is available at [Google Drive](https://drive.google.com/file/d/0B5ZM90wrDzUOM0ZfYlpDR2l1cU0/view) (from the Vigie-Chiro program).
You will also need the config files available at [Google Drive](https://drive.google.com/file/d/0B5ZM90wrDzUOQnBhRjNVRFM1Rkk/view) too.
You have two options :
You can either right click on the `.exe` installer and select `Open with other application` and `Wine Windows Program Loader`, or run `wine syrinxalphainst.exe` in Terminal.
### Set up app launcher
You have to create a new file `.local/share/applications/syrinx.desktop`:
```textile
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Syrinx
Comment=Acoustic analysis
Exec=/usr/bin/wine /home/$USER/.wine/drive_c/Program\ Files\ (x86)/syrinx/Syrinx.exe
Icon=/home/$USER/.wine/drive_c/Program Files (x86)/syrinx/img/vigie-chiro.png
Terminal=false
```
Change `$USER` by your unix username. To have an icon for the application launcher, you can download [`vigie-chiro.png`](/images/vigie-chiro.png).
To analyse ultrasound, with a 384 kHz sampling frequency, we have to open `Configs_syrinx/exp384.dsp`; and click on 'Load sound file' (shortcut `Ctrl+L`). To switch to other sound files in same folder, we can use `alt+arrows`. For more tips, you can view [the video of Charlotte ROEMER (Fr)](https://www.youtube.com/watch?v=BPPSw2FSLxs).
## Install and Configure Batsound 4
The procedure is quite similar with Syrinx-PC installation. We mention only key points.
### Set up app launcher
Create a new file `.local/share/applications/batsound.desktop`:
```textile
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Batsound
Comment=Acoustic analysis
Exec=/usr/bin/wine /home/$USER/.wine/drive_c/Program\ Files\ (x86)/Pettersson/Batsound4/BatSound.exe
Icon=/home/$USER/.wine/drive_c/Program Files (x86)/Pettersson/Batsound4/img/batsound.png
Terminal=false
```
(Do not forget to change `$USER` with your username.)
To have an icon displayed in your application launcher, you can download [`batsound.png`](/images/batsound.png).
### Configure Batsound to analyse ultrasounds
- Enter the `Sound/Sound Format` menu.
![Entering `Sound/Sound Format` menu](/images/batsound/enter-sound-format-menu.png)
- Change `Time expansion` value to 10 (according to your recorder settings)
- Keep 44 100 as `Samples per second` value.
- Enter the `Analysis/Spectrogram Settings - Defaults` menu.
![Entering `Spectrogram Setting - Defaults` menu](/images/batsound/spectrogram-settings-default-values.png)
- Change `Max frequency` to `150000`;
- Set `Amplitude color mapping` to `Yellow, Red & Blue`;
- Adapt `Threshold` to sound intensity.
- You can zoom in.
With a _Pipistrellus kuhlii_ record, I obtain the following spectrogram with the above settings:
![pipkuh spectro](/images/batsound/pipkuh-spectro-batsound.png)
## Install 7-zip
7-zip is useful in Vigie-Chiro process to compress audio files for faster upload to [https://vigiechiro.herokuapp.com](https://vigiechiro.herokuapp.com).
1. Download `.exe` installer at [https://www.7-zip.org/](https://www.7-zip.org/)
2. Execute `7z1900.exe` with wine.
## Install Lupas-Rename
Lupas-Rename is used in Vigie-Chiro protocole to batch rename audio file to add protocoles informations such as pass and square.
1. Download `.exe` installer at [https://rename.lupasfreeware.org/download.php](https://rename.lupasfreeware.org/download.php)
2. Execute installer with wine
3. Batch rename audio files...
## Conclusion
With all these softwares running on your Linux PC, you will be able to perform Vigie-Chiro protocole and sound analysis! I look forward to see your participations at <https://vigiechiro.herokuapp.com/>!
<!-- LocalWords: spectrograms
-->

View File

@ -0,0 +1,191 @@
---
title: Analyser des sons pour le programme Vigie-Chiro sur votre machine GNU/Linux avec Wine
author: Samuel Ortion
date: 2024-05-18
tags: [audio, bat, bird, ultrasound, syrinx, batsound]
lang: fr
slug: analyser-des-ultrasons-sur-gnulinux-avec-wine
---
Après avoir enregistré des sons de chauve-souris, orthoptères ou d'oiseaux, il est souvent utile de jeter un oeil aux spectrogrammes des enregistrements, par exemple lors de l'analyse d'enregistrements réalisés dans le cadre du [programme Vigie-Chiro](http://www.vigienature.fr/fr/chauves-souris).
Les logiciels recommandés dans les tutoriels Vigie-Chiro sont, pour certains, développés uniquement pour Windows. Dans cet article, nous apprendrons comment installer ces logiciels (Kaleidoscope, Syrinx, Batsound 4, 7-zip et Lupas-Rename) sur une machine Linux à l'aide de [Wine](https://winehq.org/).
## Comment installer Wine ?
Wine est un logiciels qui permet de faire tourner des logiciels Windows (`.exe`) sur un système d'exploitation UNIX comme Linux, ou Mac OS.
### Sur une machine Debian (et certaines distributions dérivées utilisant `apt` pour la gestion des logiciels)
On commence par activer le support des paquets 32 bit, si ce n'est pas déjà fait.
```bash
sudo dpkg --add-architecture i386
```
Ensuite, on télécharge et on installe la clé du dépôt deb de wine:
```bash
wget -nc https://dl.winehq.org/wine-builds/winehq.key
sudo apt-key add winehq.key
```
On ajoute l'adresse du dépôt à la liste des sources, soit directement sur `/etc/apt/source.list`, ou mieux, dans un fichier `/etc/apt/sources.list.d/wine.list`
```textile
deb https://dl.winehq.org/wine-builds/debian/ bookworm main
```
Il faudra peut être modifier le nom de la distribution et le nom de code de la version installée sur votre machine.
On met à jour la liste des paquets:
```bash
sudo apt update
```
Enfin, on installe wine (on choisit la version stable, qui devrait bien marcher pour ces logiciels).
```bash
sudo apt install --install-recommends winehq-stable
```
### Sur une Fedora, RHEL, et dérivées
On ajoute le dépôt RPM:
```bash
dnf config-manager --add-repo https://dl.winehq.org/wine-builds/fedora/39/winehq.repo
```
Ici aussi, la version 'fedora39' est à adapter à la version de l'OS que vous avez sur votre machine.
On installe wine:
```bash
dnf install winehq-stable
```
Pour plus de détails et des informations pour d'autres systèmes, ou davantage à jour: se référer au [wiki de Wine](https://wiki.winehq.org).
## Installer Kaleidoscope
Kaleidoscope est disponible pour les distributions basées sur Fedora, comme celles basées sur Debian via le site officiel <https://www.wildlifeacoustics.com/>. Il n'est pas utile d'utiliser wine pour faire fonctionner ce logiciel: il est préférable d'installer les versions adaptées pour votre système si celui-ci est supporté.
## Installer Syrinx
Comme beaucoup des logiciels présentés ici, Syrinx n'est pas conçu pour Linux. Nous avons besoin de Wine pour lancer l'exécutable `.exe`.
Syrinx-PC est disponible depuis le site de Vigie-Chiro, via un lien [Google Drive](https://drive.google.com/file/d/0B5ZM90wrDzUOM0ZfYlpDR2l1cU0/view). Vous aurez aussi besoin des fichiers de configurations proposés par Vigie-Chiro sur [Google Drive](https://drive.google.com/file/d/0B5ZM90wrDzUOQnBhRjNVRFM1Rkk/view).
Ici, nous avons deux options:
Soit on clique sur le `.exe` et on sélectionne 'Ouvrir avec une autre application', puis on choisit 'Wine Windows Program Loader', soit un lance
```console
$ wine syrinxalphainst.exe
```
depuis le terminal.
### Configurer un lanceur d'application pour Syrinx
Pour faciliter le lancement de l'application, on peut créer un fichier `~/.local/share/applications/syrinx.desktop`, dans le dossier 'home' de l'utilisateur:
```textile
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Syrinx
Comment=Acoustic analysis
Exec=/usr/bin/wine /home/$USER/.wine/drive_c/Program\ Files\ (x86)/syrinx/Syrinx.exe
Icon=/home/$USER/.wine/drive_c/Program Files (x86)/syrinx/img/vigie-chiro.png
Terminal=false
```
N'oublier pas de changer `$USER` par votre nom d'utilisateur.
Pour qu'une icône s'affiche dans le lanceur, vous pouvez télécharger l'image [`vigie-chiro.png`](/images/vigie-chiro.png).
Ensuite, pour analyser les ultrasons avec une fréquence d'échantillonage de 384 kHz en expansion de temps x10 on ouvre le fichier `Configs_syrinx/exp384.dsp` (disponible sur le site du programme Vigie-Chiro); et on clique sur `Load sound file` (`Ctrl+L`) pour charger le fichier `.wav` à analyser. Pour changer de fichier au sein du même dossier, on peut utiliser le raccourcis clavier `alt+ <fleche>`. Pour plus d'astuces pour manier ce logiciel efficacement, vous pouvez consulter [le tuto vidéo de Charlotte ROEMER](https://www.youtube.com/watch?v=BPPSw2FSLxs).
## Installer et configurer Batsound 4
La procédure est très similaire à celle présentée pour Syrinx PC. On ne détaillera que les points clés.
### Créer un lancer d'application pour batsound
Comme pour Syrinx, on crée un fichier `.desktop`: `~/.local/share/applications/batsound.desktop`:
```textile
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Batsound
Comment=Acoustic analysis
Exec=/usr/bin/wine /home/$USER/.wine/drive_c/Program\ Files\ (x86)/Pettersson/Batsound4/BatSound.exe
Icon=/home/$USER/.wine/drive_c/Program Files (x86)/Pettersson/Batsound4/img/batsound.png
Terminal=false
```
(Encore une fois, il ne faut pas oublier de changer `$USER` par votre nom d'utilisateur UNIX.)
Pour l'icône, vous pouvez télécharger [`batsound.png`](/images/batsound.png), ou un logo officiel depuis le site de l'éditeur du logiciel.
### Configurer Batsound pour l'analyse d'ultrasons
Voici un mémo rapide des différents paramètres que j'utilise avec Batsound.
- Entrer dans le menu `Sound/Sound Format`.
![Le menu `Sound/Sound Format`](/images/batsound/enter-sound-format-menu.png)
- Mettre la valeur `Time expansion` à 10 (ou 1, suivant le paramètrage de votre enregistreur, et si vous avez expansé les enregistrement
- Garder 44100 pour le paramètre `Samples per second` (là aussi, cela peut varier selon le fichier son).
- Dans le menu `Analysis/Spectrogram Settings - Defaults`:
![Le menu `Spectrogram Setting - Defaults`](/images/batsound/spectrogram-settings-default-values.png)
- Mettre `Max frequency` à `150000`;
- Choisir `Yellow, Red & Blue` pour `Amplitude color mapping`;
- Adapter la valeur `Threshold` en fonction de l'intensité du son enregistré.
- Vous pouvez zoomer.
Avec un petit enregistrement de pipistrelle de Kuhl (_Pipistrellus kuhlii_), j'ai obtenu le spectrogramme suivant:
![pipkuh spectro](/images/batsound/pipkuh-spectro-batsound.png)
## Installer 7-zip
7-zip est utile dans Vigie-Chiro pour compresser les dossiers d'enregistrements traités, afin d'accélérer le téléchargement sur
<https://vigiechiro.herokuapp.com/>.
Il est recommendé d'utiliser l'outil p7zip fourni pour Linux, mais si vous souhaitez suivre le tutoriel de Vigie-Chiro avec l'interface graphique Windows, vous pouvez aussi installer le logiciel 7-zip graphique prévu pour ce système d'exploitation:
1. Télécharger l'installeur `.exe` depuis [https://www.7-zip.org/](https://www.7-zip.org/)
2. Lancer `7z1900.exe` avec `wine`:
```console
wine 7z1900.exe
```
## Installer Lupas-Rename
Lupas-Rename est utilisé dans le tutoriel de Vigie-Chiro, pour faciliter le renommage des fichiers sons suivant le format de nom de fichier des protocoles. Là aussi, il est probablement plus efficace d'utiliser les outils disponible sous votre machine Linux, en ligne de commande ou via un outil graphique proposé par votre distribution, mais néanmoins, voici la procédure qui vous permettrait d'installer Lupas-Rename sur votre machine, toujours à l'aide de `wine`.
1. Télécharger l'installeur `.exe` depuis <https://rename.lupasfreeware.org/download.php>
2. Exécuter l'installeur avec wine
3. Suivre la procédure décrite dans le tutoriel pour renommer les fichiers audio...
## `tadam.py!` pour traiter vos nuits d'enregistrements en une ligne de commande
J'ai écris un [petit script Python](https://forge.chapril.org/Chiro-Canto/TadaridaTools/src/branch/master/src/tadam.py) qui tente d'automatiser au maximum toute la procédure des fichiers sons brutes, aux archives de son compressées (incluant l'expansion de temps des son, si besoin) destinées au téléchargement sur la plateforme Vigie-Chiro.
Un [petit peu de documentation en français](https://forge.chapril.org/Chiro-Canto/TadaridaTools/src/branch/master/docs/fr/TADAM.md) est disponible dans le même dépôt.
## ChiroSurf
[ChiroSurf](https://vigie-chiro.forumactif.com/t108-chirosurf-2-4-analyse-bioacoustique-gratuit-portable-24-04-24) est un logiciel gratuit développé par un bénévole pour le programme Vigie-Chiro. Ce logiciel s'installe bien sur Linux, avec wine et en utilisant le `.exe` (car il n'y a pas de version prévue pour Linux, malheureusement).
## Conclusion
Avec tous ces logiciels installés sur votre machine Linux, vous devriez être capable de participer au traitement et à l'analyse des fichiers son pour le protocole Vigie-Chiro, sans quitter votre machine Linux !
<!-- LocalWords: spectrogramme
-->

View File

@ -1,158 +0,0 @@
---
title: Analyse Sound on GNU/Linux using Wine
author: Samuel Ortion
date: 2021-03-25
tags: [audio, bat, bird, ultrasound, syrinx, batsound]
lang: en
---
After recording bats, orthoptera or birds, it is often necesserary to see the spectrograms of the sounds, for instance while analysing [Vigie-Chiro Program](http://www.vigienature.fr/fr/chauves-souris) bat records
The software needed to do so are often only for Windows, in the present article, we will learn how to install these softwares (i.e. Kaleidoscope, Syrinx, Batsound 4, 7-zip, Lupas-Rename).
Install Wine
------------
Wine is a software that enable .exe software to run on UNIX systems such as Linux or Mac OS.
### On Debian and derivatives (Ubuntu...)
Enable 32 bit packages (if you haven't already):
```bash
sudo dpkg --add-architecture i386
```
Download and install the repository key:
```bash
wget -nc https://dl.winehq.org/wine-builds/winehq.key
sudo apt-key add winehq.key
```
Add the repository to /etc/apt/sources.list or create a wine.list under /etc/apt/sources.list.d/ with the following content:
```textile
deb https://dl.winehq.org/wine-builds/debian/ buster main
```
Update packages
```bash
sudo apt update
```
Install Wine stable
```bash
sudo apt install --install-recommends winehq-stable
```
### On Fedora, RHEL, and derivatives
Add repository :
```bash
dnf config-manager --add-repo https://dl.winehq.org/wine-builds/fedora/33/winehq.repo
```
Install stable package :
```bash
dnf install winehq-stable
```
Install Kaleidoscope
--------------------
Kaleidoscope is available on both fedora and debian based distros at [wildlife acoustics](https://www.wildlifeacoustics.com/).
Install Syrinx
--------------
As all following softwares, Syrinx is not available for GNU/Linux, we need Wine to execute the `.exe`.
Syrinx-PC is available at [Google Drive](https://drive.google.com/file/d/0B5ZM90wrDzUOM0ZfYlpDR2l1cU0/view).
You will also need the config files available at [Google Drive](https://drive.google.com/file/d/0B5ZM90wrDzUOQnBhRjNVRFM1Rkk/view).
You have almost two options :
You can either right click on the `.exe` installer and select `Open with other application` and `Wine Windows Program Loader`, or either run `wine syrinxalphainst.exe` in Terminal.
### Set up app launcher
You have to create a new file `.local/share/applications/syrinx.desktop`:
```textile
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Syrinx
Comment=Acoustic analysis
Exec=/usr/bin/wine /home/<USER>/.wine/drive_c/Program\ Files\ (x86)/syrinx/Syrinx.exe
Icon=/home/<USER>/.wine/drive_c/Program Files (x86)/syrinx/img/vigie-chiro.png
Terminal=false
```
Change `<USER>` by your username. To have the icon, you can download [`vigie-chiro.png`](/images/vigie-chiro.png).
To analyse ultrasound, with a 384 kHz sampling frequency, we have to open `Configs_syrinx/exp384.dsp`; and next Load sound file (`Ctrl+L`). To switch to other sound file in same folder, we can use `alt+arrows`. For more tips, you can view [the video of Charlotte ROEMER (Fr)](https://www.youtube.com/watch?v=BPPSw2FSLxs).
Install and Configure Batsound 4
--------------------------------
The procedure is quite similar with Syrinx-PC installation.
### Set up app launcher
Create a new file `.local/share/applications/batsound.desktop`:
```textile
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Batsound
Comment=Acoustic analysis
Exec=/usr/bin/wine /home/<USER>/.wine/drive_c/Program\ Files\ (x86)/Pettersson/Batsound4/BatSound.exe
Icon=/home/<USER>/.wine/drive_c/Program Files (x86)/Pettersson/Batsound4/img/batsound.png
Terminal=false
```
(Do not forget to change `<USER>` to your username.)
To have the icon, you can download [`batsound.png`](/images/batsound.png).
### Configure Batsound to analyse ultrasounds
* Enter the `Sound/Sound Format` menu.
![Entering `Sound/Sound Forma` menu](/images/batsound/enter-sound-format-menu.png)
* Change `Time expansion` value to 10 (according to your recorder settings)
* Keep 44 100 as `Samples per second` value.
* Enter the `Analysis/Spectrogram Settings - Defaults` menu.
![Entering `Spectrogram Setting - Defaults` menu](/images/batsound/spectrogram-settings-default-values.png)
* Change `Max frequency` to `150000`;
* Set `Amplitude color mapping` to `Yellow, Red & Blue`;
* Adapt `Threshold` to sound intensity.
* You can zoom in.
With a *Pipistrellus kuhlii* record, I obtain the following spectrogram with the above settings :
![pipkuh spectro](/images/batsound/pipkuh-spectro-batsound.png)
Install 7-zip
-------------
7-zip is useful in Vigie-Chiro process to compress audio files for faster upload to [https://vigiechiro.herokuapp.com](https://vigiechiro.herokuapp.com).
1. Download `.exe` installer at [https://www.7-zip.org/](https://www.7-zip.org/)
2. Execute `7z1900.exe` with wine.
Install Lupas-Rename
--------------------
Lupas-Rename is used in Vigie-Chiro protocole to batch rename audio file to add protocoles informations such as pass and square.
1. Dowload `.exe` installer at [https://rename.lupasfreeware.org/download.php](https://rename.lupasfreeware.org/download.php)
2. Execute installer with wine
3. Batch rename audio files...
Conclusion
----------
With all these functionnal softwares, you are able to perform Vigie-Chiro protocole and sound analysis on GNU/Linux. I look forward to see your participation at [https://vigiechiro.herokuapp.com](https://vigiechiro.herokuapp.com) !

View File

@ -4,6 +4,7 @@ author: Samuel Ortion
date: 2022-06-12
tags: [math]
lang: en
draft: true
---
## Install plotutils

View File

@ -6,6 +6,7 @@ tags: [math, latex, pelican]
slug: rendering-latex-pelican
author: Samuel Ortion
lang: en
draft: true
---
Rendering $\LaTeX$ formulas in Pelican is easy.

View File

@ -1,24 +1,24 @@
---
title: Install Gephi on Linux
date: 2022-06-19
lastmod: 2022-06-19
lastmod: 2024-05-18
tags: [graph, visualization, linux]
slug: install-gephi-on-linux
author: Samuel Ortion
lang: en
draft: true
---
Gephi is a software package for graph visualization. Let's install it on Linux.
## Install Gephi
Don't forget to update the release version in the URL, as well as in the resulting decompressed folder name.
```bash
su - # Switch to root
cd /opt/
wget https://github.com/gephi/gephi/releases/download/v0.9.5/gephi-0.9.5-linux-x64.tar.gz -o
wget https://github.com/gephi/gephi/releases/download/v0.9.5/gephi-0.9.5-linux-x64.tar.gz
tar -xzf gephi-0.9.5-linux-x64.tar.gz
rm gephi-0.9.5-linux-x64.tar.gz
cd gephi-0.9.5
sudo mv gephi-0.9.5 /opt/gephi
```
Now you could use it by running `./bin/gephi` in the terminal.
@ -27,27 +27,21 @@ Now you could use it by running `./bin/gephi` in the terminal.
For an easier access, you could add a desktop entry to your menu.
In `/home/$USER/.local/share/applications/gephi.desktop`:
```text
// /home/$USER/.local/share/applications/gephi.desktop
[Desktop Entry]
Name=Gephi
Comment=Launch Gephi
Path=/opt/gephi-0.9.5/
Exec=/opt/gephi-0.9.5/bin/gephi
Path=/opt/gephi/
Exec=/opt/gephi/bin/gephi
Terminal=true
Type=Application
Icon=gephi.jpg
Icon=gephi-tool-icon-200x200-1.jpg
StartupNotify=true
Categories=Development;Education;
Keywords=graph;
```
And download a logo for your application.
```bash
cd /opt/gephi-0.9.5/
wget https://dighumlab.org/wp-content/uploads/2020/03/gephi-tool-icon-200x200-1.jpg -o gephi.jpg
```
That's it !

View File

@ -172,4 +172,4 @@ ggplot(data = languages_count_df, aes(x = reorder(language, count), y = count))
ggsave("linguist-project-count.png", width = 10, height = 5)
```
<img src="/images/R/linguist-project-count.png" alt="bar plots of languages I used, according to github-linguist">
<img src="/images/R/languages_count.png" alt="bar plots of languages I used, according to github-linguist">

View File

@ -7,6 +7,7 @@ slug: classify-blood-cells-using-neural-networks
author: Samuel Ortion
Summary: Machine Learning is widely used for image recognition. Here, we tried to perform blood cell classification using Convolutional Neural Networks.
lang: en
draft: true
---
## Introduction

View File

@ -2,7 +2,7 @@
#+date: <2024-01-14 Sun>
#+category: linux
A bin for some useful UNIX command.
A bean for some useful UNIX command snippets.
* Add two hours

View File

@ -13,19 +13,9 @@ Here is what I did to make this working on my blog.
In your theme files, you will first need to add link to the library CDN.
```html
<!-- in themes/<theme>/layouts/partials/pseucodode.html -->
<script>
MathJax = {
tex: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [['$$','$$'], ['\\[','\\]']],
processEscapes: true,
processEnvironments: true,
}
}
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-chtml-full.js"
integrity="sha256-kbAFUDxdHwlYv01zraGjvjNZayxKtdoiJ38bDTFJtaQ="
crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.js"
integrity="sha512-EKW5YvKU3hpyyOcN6jQnAxO/L8gts+YdYV6Yymtl8pk9YlYFtqJgihORuRoBXK8/cOIlappdU6Ms8KdK6yBCgA=="
crossorigin="anonymous" referrerpolicy="no-referrer">
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pseudocode@latest/build/pseudocode.min.css">
<script src="https://cdn.jsdelivr.net/npm/pseudocode@latest/build/pseudocode.min.js"></script>

View File

@ -0,0 +1,135 @@
---
title: Find an Eulerian Path with the Hierholzer Algorithm
date: 2024-03-13
pseudocode: true
slug: hierholzer-algorithm
draft: true
---
An Eulerian path of a graph is a path that passes once on every edge of the graph.
The Hierholzer algorithm allows to find this path.
The algorithm proceeds as follows:
1. Choose any vertex $v_0$ of the graph $G = (V, E)$. Starting from $v_0$, build a path $c$ that passes only once per edge until it reaches $v_0$ again.
2. If $c$ is an Eulerian cycle, we have found the Eulerian path, else
- Ignore all edges from $c$.
- For the first vertex $u$ from $c$ whose degree is not null, build an other cycle $c'$ that passes only once per edges, and does not pass in the previously visited edges.
- Insert $c'$ in $c$ by replacing the starting node $u$.
- Repeat the second step until we have an Eulerian path.
## Pseudocode
<pre class="pseudocode">
\begin{algorithm}
\caption{Hierholzer algorithm for Eulerian path finding}
\begin{algorithmic}
\Function{EulerianPath}{$G: (V, E)$}
\State $c \gets$ an empty Doubly Linked List
\State $E' \gets E$
\State $v_0$ becomes the first vertex from $V$
\State $u \gets v_0$
\State \Comment{Find the first cycle}
\While{$\exists (u, v) \in E'$}
\State $c$.insert($u$)
\State $u \gets v$
\State $E' \gets E' \setminus \{(u, v)\}$
\If {$u = v_0$}
\Break
\EndIf
\EndWhile
\State \Comment{Add the other cycles}
\While {$c$.length $< |E|$}
\State \Comment{Find the next vertex with non null degree}
\State $v_0 \gets c$.value
\While {$\nexists (v_0, v) \in E'$}
\State $c \gets c$.next
\State $v_0 \gets c$.value
\State $u \gets v_0$
\EndWhile
\State \Comment{Insert the next cycle in $c$}
\State $c$.delete() \Comment{Ensure $v_0$ is not present twice there}
\While {$\exists (u, v) \in E'$}
\State $c$.insert($u$)
\State $u \gets v$
\State $E' \gets E' \setminus \{(u, v)\}$
\If {$u = v_0$}
\Break
\EndIf
\EndWhile
\EndWhile
\EndFunction
\end{algorithmic}
\end{algorithm}
</pre>
## Rust implantation
```rust
use std::collections::{HashMap, LinkedList};
use std::io::Error;
/// Eulerian path
///
/// Warning: this assumes the graph is Eulerian
fn eulerian_path(graph: HashMap<usize, Vec<usize>>) -> Option<LinkedList<usize>>
{
let mut n_edges: usize = 0;
for adj_list in graph.values() {
n_edges += adj_list.len();
}
let mut graph = graph.clone();
let mut cycle: LinkedList<usize> = LinkedList::new();
let v_0: usize = *graph.keys().next().unwrap();
let mut visited_edges: usize = 0;
let mut u: usize = v_0;
loop {
cycle.push_back(u);
let adj_list = graph.get_mut(&u).unwrap();
visited_edges += 1;
if adj_list.len() > 0 {
let v = adj_list.pop().unwrap();
u = v;
} else {
return None;
}
if u == v_0 {
break;
}
}
while visited_edges < n_edges {
// Find the next vertex with non null degree
let mut v_0 = cycle.front().unwrap().clone();
while graph.get(&v_0).unwrap().len() == 0 {
v_0 = cycle.front().unwrap().clone();
// Move to the next vertex without removing it from the cycle, with rotation
let v = cycle.pop_front().unwrap();
cycle.push_back(v);
}
// Insert the next cycle in c
cycle.pop_back();
let mut u = v_0;
loop {
cycle.push_back(u);
let adj_list = graph.get_mut(&u).unwrap();
visited_edges += 1;
if adj_list.len() > 0 {
let v = adj_list.pop().unwrap();
u = v;
} else {
return None;
}
if u == v_0 {
break;
}
}
}
Some(cycle)
}
```
## References
- _Algorithmus von Hierholzer_ (de), Wikipedia, <https://de.wikipedia.org/wiki/Algorithmus_von_Hierholzer>.
- _Eulerkreisproblem_ (de), Wikipedia, <https://de.wikipedia.org/wiki/Eulerkreisproblem>

View File

@ -0,0 +1,28 @@
---
title: "Mixed-radix generation -"
author: ["Samuel Ortion"]
date: 2024-04-15T00:00:00+02:00
draft: true
pseudocode: true
---
In its draft on Generating all \\(n\\) tuples, of The Art of Computer Programming, Knuth presents the following algorithm for the generation of $n$-tuples (<a href="#citeproc_bib_item_1">Knuth 2002</a>).
<pre id="hello-world-code" class="pseudocode">
\begin{algorithm}
\caption{Mixed-radix generation}
\begin{algorithmic}
\State \textbf{M1.} [Initialize.] Set $a_j \gets 0$ for $0 \leq j \leq n$, and set $m_0 \gets 2$.
\State \textbf{M2.} [Visit.] Visit the \(n\)-tuple $(a_1, ..., a_n)$ (The program that wants to examine all $n$-tuples now does its thing.)
\State \textbf{M3.} [Prepare to add one.] Set $j \gets n$.
\State \textbf{M4.} [Carry if necessary.] If $a_j = m_j - 1$, set $a_j \gets 0$, $j \gets j - 1$ and repeat this step.
\State \textbf{M5.} [Increase, unless done.] If $j = 0$, terminate the algorithm. Otherwise set $a_j \gets a_j + 1$ and go back to step M2.
\end{algorithmic}
\end{algorithm}
</pre>
## References
<style>.csl-entry{text-indent: -1.5em; margin-left: 1.5em;}</style><div class="csl-bib-body">
<div class="csl-entry"><a id="citeproc_bib_item_1"></a>Knuth, Donald E. 2002. <i>A Draft of Section 7.2.1.1: Generating All N-Tuples</i>. Vol. 4a. 5 vols. The Art of Computer Programming.</div>
</div>

View File

@ -0,0 +1,88 @@
+++
title = "Le problème de couverture par sommets en Integer Linear Programming avec LP-solve"
author = ["Samuel Ortion"]
date = 2025-11-01
slug = "couverture-par-sommets-optimisation-linéaire"
tags = [["graph"]]
draft = false
+++
Le [problème de couverture par sommets](https://fr.wikipedia.org/wiki/Probl%C3%A8me_de_couverture_par_sommets) (ou _Vertex Cover_ en anglais) consiste, étant donné un graphe, à trouver un ensemble minimum de sommets de sorte que toutes les arêtes soient couvertes.
Formellement: soit \\(G(V, E)\\) un graphe, une couverture est un ensemble \\(S\\) tel que:
\\[
S \subseteq V \text{ tel que } \forall e = (u, v) \in E, u \in S, \text{ ou } v \in S
\\]
L'objectif est de miniser la taille de \\(S\\).
{{< figure src="/ox-hugo/vertex-cover-example.svg" >}}
Le problème de la couverture par sommets est NP-complet.
Dans ce post, nous allons tenter d'utiliser l'integer programming pour résoudre ce problème.
## Encodage du problème en Integer Programming {#encodage-du-problème-en-integer-programming}
En Integer Programming, on peut utiliser des variables entières, et des contraintes, telles que \\(a + b \geq c\\).
Pour encoder notre problème en Integer Programming, on va se donner une variable Booléenne \\(x\_v\\) pour chaque sommet \\(v\\), sur \\(\\{0, 1\\}\\), évaluée à 1 si \\(v\\) est sélectionné dans \\(S\\).
Puis, pour chaque arête \\((u, v)\\), on crée une contrainte pour s'assurer qu'elle soit couverte:
\\[
x\_u + x\_v \geq 1
\\]
Dans cette condition, la contrainte est satisfaite si au moins une des variables \\(x\_u\\) et \\(x\_v\\) est vraie (c'est-à-dire égale à 1).
La fonction à miniser, correspondant au cardinal de \\(S\\) est simplement:
\\[
\sum\_{v \in V} x\_v
\\]
Les valeurs de \\(x\_v\\) en sortie du solveur d'Integer Programming indiquent quel est l'ensemble \\(S\\) de la solution.
## Implementation avec LP-solve {#implementation-avec-lp-solve}
[LP-solve](https://lp-solve.github.io/) est un solveur pour le problème Mixed Integer Linear Programming.
Pour l'exemple présenté au début de ce post, le graphe est composé des arrêtes suivantes: \\((a, c),
(c, b),
(d, e),
(a, e),
(a, d)\\)
```lp_solve
min: a + b + c + d + e;
r_1: a + c >= 1;
r_2: d + e >= 1;
r_3: c + b >= 1;
r_4: a + e >= 1;
r_5: a + d >= 1;
bin a;
bin b;
bin c;
bin d;
bin e;
```
```text
Value of objective function: 3.00000000
Actual values of the variables:
a 1
b 0
c 1
d 0
e 1
```
Ce qui correspond à la couverture suivante (sommets jaunes), sur le graphe initial.
{{< figure src="/ox-hugo/vertex-cover-example-lp_solve.svg" >}}

View File

@ -17,7 +17,31 @@ J'ai donc utilisé le logiciel [Motion](https://motion-project.github.io/), qui
- Alimentation pour Raspberry Pi;
- Batterie externe USB (optionnel, utile pour obtenir un piège photo autonome);
- Caméra Raspberry Pi (avec sa nâpe de câblage), ou une caméra USB;
- Carte SD (avec assez de stockage pour les photos et l'OS);
- Carte micro SD (avec assez de stockage pour les photos et l'OS);
- Une boîte (étanche de préférence).
## Installation du système d'exploitation
Pour un piège photo, un système d'exploitation sans interface graphique suffit. On peut installer, par exemple [Raspberry Pi OS Lite](https://www.raspberrypi.com/software/operating-systems/).
L'installation du système d'exploitation est en dehors du cadre de ce tuto. Le plus simple est d'utiliser l'outil Raspberry Pi Imager. Pensez à mettre en place le service SSH, à entrer les identifiants / mots de passes de votre point d'accès WiFi.
## Installation de Motion et configuration
Motion est un logiciel qui analyse en continue le flux vidéo de la caméra et peux déclencher la prise de vue lorsqu'il détecte un changement important de couleur de pixel (quand un oiseau ou un chat passe devant la caméra par exemple).
Pour installer motion, on utilise la commande suivante:
```console
sudo apt install motion
```
Sur les versions récente de Raspberry Pi OS (basées sur Bookworm), la gestion des caméras nécessite l'utilisation de `libcamera`.
On installe donc `libcamera`:
```console
sudo apt install libcamera-tools libcamera-v4l2
```

View File

@ -134,7 +134,7 @@ void loop() {
## Results
I had the change to have a family of great tit, that were in a birdhouse I made.
I had the chance to have a family of great tit, that were in a birdhouse I made.
Here are two images taken by the Arduino Camera Trap.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

5
go.mod
View File

@ -1,5 +0,0 @@
module forge.s1gm4.eu/sortion/org-blog
go 1.21.5
require github.com/Mitrichius/hugo-theme-anubis v0.0.0-20231204175953-57eb2998cf2e // indirect

2
go.sum
View File

@ -1,2 +0,0 @@
github.com/Mitrichius/hugo-theme-anubis v0.0.0-20231204175953-57eb2998cf2e h1:oCnqB3lB2ZwWA8lDsCPWHrArSGx+/g4lqR1rX33hm/E=
github.com/Mitrichius/hugo-theme-anubis v0.0.0-20231204175953-57eb2998cf2e/go.mod h1:FKD3NbdsQzL+cXsC3x99XD/t/Rd5EyhDlNBAxQhULbo=

View File

@ -0,0 +1,125 @@
#+title: Le problème de couverture par sommets en Integer Linear Programming avec LP-solve
#+date: 2025-11-01
#+lastmod: 2025-11-01
#+hugo_tags: [graph]
#+author: Samuel Ortion
#+hugo_lang: fr
#+hugo_draft: nil
#+hugo_base_dir: ..
#+hugo_pseudocode: true
#+hugo_slug: couverture-par-sommets-optimisation-linéaire
Le [[https://fr.wikipedia.org/wiki/Probl%C3%A8me_de_couverture_par_sommets][problème de couverture par sommets]] (ou /Vertex Cover/ en anglais) consiste, étant donné un graphe, à trouver un ensemble minimum de sommets de sorte que toutes les arêtes soient couvertes.
Formellement: soit $G(V, E)$ un graphe, une couverture est un ensemble $S$ tel que:
$$
S \subseteq V \text{ tel que } \forall e = (u, v) \in E, u \in S, \text{ ou } v \in S
$$
L'objectif est de miniser la taille de $S$.
#+begin_src dot :file vertex-cover-example.svg :results file graphics
graph G {
{
node [width=0.25 shape=circle style=filled]
a
b
c
d
e
}
a -- c
c -- b
d -- e
a -- e
a -- d
}
#+end_src
#+RESULTS:
[[file:vertex-cover-example.svg]]
Le problème de la couverture par sommets est NP-complet.
Dans ce post, nous allons tenter d'utiliser l'integer programming pour résoudre ce problème.
* Encodage du problème en Integer Programming
En Integer Programming, on peut utiliser des variables entières, et des contraintes, telles que $a + b \geq c$.
Pour encoder notre problème en Integer Programming, on va se donner une variable Booléenne $x_v$ pour chaque sommet $v$, sur $\{0, 1\}$, évaluée à 1 si $v$ est sélectionné dans $S$.
Puis, pour chaque arête \((u, v)\), on crée une contrainte pour s'assurer qu'elle soit couverte:
$$
x_u + x_v \geq 1
$$
Dans cette condition, la contrainte est satisfaite si au moins une des variables $x_u$ et $x_v$ est vraie (c'est-à-dire égale à 1).
La fonction à miniser, correspondant au cardinal de $S$ est simplement:
\[
\sum_{v \in V} x_v
\]
Les valeurs de $x_v$ en sortie du solveur d'Integer Programming indiquent quel est l'ensemble $S$ de la solution.
* Implementation avec LP-solve
[[https://lp-solve.github.io/][LP-solve]] est un solveur pour le problème Mixed Integer Linear Programming.
Pour l'exemple présenté au début de ce post, le graphe est composé des arrêtes suivantes: \((a, c),
(c, b),
(d, e),
(a, e),
(a, d)\)
#+begin_src lp_solve :exports both
min: a + b + c + d + e;
r_1: a + c >= 1;
r_2: d + e >= 1;
r_3: c + b >= 1;
r_4: a + e >= 1;
r_5: a + d >= 1;
bin a;
bin b;
bin c;
bin d;
bin e;
#+end_src
#+RESULTS:
:
: Value of objective function: 3.00000000
:
: Actual values of the variables:
: a 1
: b 0
: c 1
: d 0
: e 1
Ce qui correspond à la couverture suivante (sommets jaunes), sur le graphe initial.
#+begin_src dot :file vertex-cover-example-lp_solve.svg :results file graphics
graph G {
{
node [width=0.25 shape=circle style=filled]
a [fillcolor=yellow]
b
c [fillcolor=yellow]
d
e [fillcolor=yellow]
}
a -- c
c -- b
d -- e
a -- e
a -- d
}
#+end_src
#+RESULTS:
[[file:vertex-cover-example-lp_solve.svg]]

View File

@ -0,0 +1,71 @@
#+title: Mixed-radix generation - TAOCP
#+date: <2024-04-15 Mon>
#+category: taocp
#+pseudocode: true
#+bibliography: references.bib
#+slug: taocp/permutations
#+hugo_draft: true
#+hugo_front_matter_format: yaml
#+hugo_base_dir: ../../
#+hugo_custom_front_matter: :pseudocode true
In his draft on Generating all $n$ tuples, of The Art of Computer Programming, Knuth presents the following algorithm for the generation of $n$-tuples [cite:@knuthDraftSectionGenerating2002].
#+begin_export html
<pre id="hello-world-code" class="pseudocode">
\begin{algorithm}
\caption{Mixed-radix generation}
\begin{algorithmic}
\State \textbf{M1.} [Initialize.] Set $a_j \gets 0$ for $0 \leq j \leq n$, and set $m_0 \gets 2$.
\State \textbf{M2.} [Visit.] Visit the \(n\)-tuple $(a_1, ..., a_n)$ (The program that wants to examine all $n$-tuples now does its thing.)
\State \textbf{M3.} [Prepare to add one.] Set $j \gets n$.
\State \textbf{M4.} [Carry if necessary.] If $a_j = m_j - 1$, set $a_j \gets 0$, $j \gets j - 1$ and repeat this step.
\State \textbf{M5.} [Increase, unless done.] If $j = 0$, terminate the algorithm. Otherwise set $a_j \gets a_j + 1$ and go back to step M2.
\end{algorithmic}
\end{algorithm}
</pre>
#+end_export
In this document, I try to implement this algorithm in C.
#+begin_src C
#include<stdio.h>
#include<stdlib.h>
void print_array(unsigned short int *a, size_t n) {
for (size_t i=0; i < n; i++) {
printf("%d", a[i]);
if (i < n - 1) {
printf(", ");
} else {
printf("\n");
}
}
}
/** Apply function fun on the generated permutations
,*/
void mixed_radix(const size_t n, void (*fun)()) {
// Initialize
unsigned short int a[n];
unsigned short int m_0 = 2;
// Visit
fun(a);
// Prepare to add one
size_t j = n;
// Carry if necessary
if (a[j] == )
}
void main() {
const size_t n = 4;
unsigned short int a[n];
print_array(a, n);
}
#+end_src
#+RESULTS:
| 0 | 0 | 0 | 0 |
#+print_bibliography:

10
org/taocp/references.bib Normal file
View File

@ -0,0 +1,10 @@
@mvbook{knuthDraftSectionGenerating2002,
title = {A Draft of Section 7.2.1.1: Generating All n-Tuples},
author = {Knuth, Donald E.},
date = {2002-03-30},
series = {The {{Art}} of {{Computer Programming}}},
volume = {4a},
langid = {english},
pagetotal = {200},
volumes = {5}
}

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.42.4 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="120pt" height="189pt"
viewBox="0.00 0.00 120.06 188.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184.89)">
<title>G</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-184.89 116.06,-184.89 116.06,4 -4,4"/>
<!-- a -->
<g id="node1" class="node">
<title>a</title>
<ellipse fill="yellow" stroke="black" cx="71.38" cy="-163.22" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="71.38" y="-159.52" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<ellipse fill="yellow" stroke="black" cx="18.38" cy="-91.15" rx="16.94" ry="16.94"/>
<text text-anchor="middle" x="18.38" y="-87.45" font-family="Times,serif" font-size="14.00">c</text>
</g>
<!-- a&#45;&#45;c -->
<g id="edge1" class="edge">
<title>a&#45;&#45;c</title>
<path fill="none" stroke="black" d="M61.17,-148.71C51.66,-136.14 37.59,-117.55 28.21,-105.15"/>
</g>
<!-- d -->
<g id="node4" class="node">
<title>d</title>
<ellipse fill="lightgrey" stroke="black" cx="71.38" cy="-91.15" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="71.38" y="-87.45" font-family="Times,serif" font-size="14.00">d</text>
</g>
<!-- a&#45;&#45;d -->
<g id="edge5" class="edge">
<title>a&#45;&#45;d</title>
<path fill="none" stroke="black" d="M71.38,-145.26C71.38,-134.57 71.38,-120.78 71.38,-109.94"/>
</g>
<!-- e -->
<g id="node5" class="node">
<title>e</title>
<ellipse fill="yellow" stroke="black" cx="94.38" cy="-18.38" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="94.38" y="-14.68" font-family="Times,serif" font-size="14.00">e</text>
</g>
<!-- a&#45;&#45;e -->
<g id="edge4" class="edge">
<title>a&#45;&#45;e</title>
<path fill="none" stroke="black" d="M80.91,-148.19C87.25,-137.97 95.01,-123.52 98.38,-109.54 104.45,-84.41 101.03,-54.22 97.84,-35.94"/>
</g>
<!-- b -->
<g id="node2" class="node">
<title>b</title>
<ellipse fill="lightgrey" stroke="black" cx="18.38" cy="-18.38" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="18.38" y="-14.68" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- c&#45;&#45;b -->
<g id="edge2" class="edge">
<title>c&#45;&#45;b</title>
<path fill="none" stroke="black" d="M18.38,-74.1C18.38,-63 18.38,-48.26 18.38,-36.87"/>
</g>
<!-- d&#45;&#45;e -->
<g id="edge3" class="edge">
<title>d&#45;&#45;e</title>
<path fill="none" stroke="black" d="M76.84,-73.38C80.55,-61.94 85.45,-46.86 89.13,-35.55"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.42.4 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="120pt" height="189pt"
viewBox="0.00 0.00 120.06 188.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184.89)">
<title>G</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-184.89 116.06,-184.89 116.06,4 -4,4"/>
<!-- a -->
<g id="node1" class="node">
<title>a</title>
<ellipse fill="lightgrey" stroke="black" cx="71.38" cy="-163.22" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="71.38" y="-159.52" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<ellipse fill="lightgrey" stroke="black" cx="18.38" cy="-91.15" rx="16.94" ry="16.94"/>
<text text-anchor="middle" x="18.38" y="-87.45" font-family="Times,serif" font-size="14.00">c</text>
</g>
<!-- a&#45;&#45;c -->
<g id="edge1" class="edge">
<title>a&#45;&#45;c</title>
<path fill="none" stroke="black" d="M61.17,-148.71C51.66,-136.14 37.59,-117.55 28.21,-105.15"/>
</g>
<!-- d -->
<g id="node4" class="node">
<title>d</title>
<ellipse fill="lightgrey" stroke="black" cx="71.38" cy="-91.15" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="71.38" y="-87.45" font-family="Times,serif" font-size="14.00">d</text>
</g>
<!-- a&#45;&#45;d -->
<g id="edge5" class="edge">
<title>a&#45;&#45;d</title>
<path fill="none" stroke="black" d="M71.38,-145.26C71.38,-134.57 71.38,-120.78 71.38,-109.94"/>
</g>
<!-- e -->
<g id="node5" class="node">
<title>e</title>
<ellipse fill="lightgrey" stroke="black" cx="94.38" cy="-18.38" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="94.38" y="-14.68" font-family="Times,serif" font-size="14.00">e</text>
</g>
<!-- a&#45;&#45;e -->
<g id="edge4" class="edge">
<title>a&#45;&#45;e</title>
<path fill="none" stroke="black" d="M80.91,-148.19C87.25,-137.97 95.01,-123.52 98.38,-109.54 104.45,-84.41 101.03,-54.22 97.84,-35.94"/>
</g>
<!-- b -->
<g id="node2" class="node">
<title>b</title>
<ellipse fill="lightgrey" stroke="black" cx="18.38" cy="-18.38" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="18.38" y="-14.68" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- c&#45;&#45;b -->
<g id="edge2" class="edge">
<title>c&#45;&#45;b</title>
<path fill="none" stroke="black" d="M18.38,-74.1C18.38,-63 18.38,-48.26 18.38,-36.87"/>
</g>
<!-- d&#45;&#45;e -->
<g id="edge3" class="edge">
<title>d&#45;&#45;e</title>
<path fill="none" stroke="black" d="M76.84,-73.38C80.55,-61.94 85.45,-46.86 89.13,-35.55"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.42.4 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="80pt" height="134pt"
viewBox="0.00 0.00 80.00 134.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 130)">
<title>G</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-130 76,-130 76,4 -4,4"/>
<!-- a -->
<g id="node1" class="node">
<title>a</title>
<ellipse fill="yellow" stroke="black" cx="45" cy="-117" rx="9" ry="9"/>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<ellipse fill="lightgrey" stroke="black" cx="9" cy="-63" rx="9" ry="9"/>
</g>
<!-- a&#45;&#45;c -->
<g id="edge1" class="edge">
<title>a&#45;&#45;c</title>
<path fill="none" stroke="black" d="M40.29,-109.2C33.43,-99.29 20.75,-80.97 13.82,-70.97"/>
</g>
<!-- d -->
<g id="node4" class="node">
<title>d</title>
<ellipse fill="lightgrey" stroke="black" cx="45" cy="-63" rx="9" ry="9"/>
</g>
<!-- a&#45;&#45;d -->
<g id="edge5" class="edge">
<title>a&#45;&#45;d</title>
<path fill="none" stroke="black" d="M45,-107.88C45,-98.16 45,-82 45,-72.24"/>
</g>
<!-- e -->
<g id="node5" class="node">
<title>e</title>
<ellipse fill="lightgrey" stroke="black" cx="63" cy="-9" rx="9" ry="9"/>
</g>
<!-- a&#45;&#45;e -->
<g id="edge4" class="edge">
<title>a&#45;&#45;e</title>
<path fill="none" stroke="black" d="M48.97,-108.8C53.41,-100.3 60.32,-85.61 63,-72 66.74,-52.99 65.22,-30.06 63.99,-18.12"/>
</g>
<!-- b -->
<g id="node2" class="node">
<title>b</title>
<ellipse fill="yellow" stroke="black" cx="9" cy="-9" rx="9" ry="9"/>
</g>
<!-- c&#45;&#45;b -->
<g id="edge2" class="edge">
<title>c&#45;&#45;b</title>
<path fill="none" stroke="black" d="M9,-53.88C9,-44.16 9,-28 9,-18.24"/>
</g>
<!-- d&#45;&#45;e -->
<g id="edge3" class="edge">
<title>d&#45;&#45;e</title>
<path fill="none" stroke="black" d="M47.66,-54.33C51.06,-44.5 56.92,-27.55 60.33,-17.7"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.42.4 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="120pt" height="189pt"
viewBox="0.00 0.00 120.06 188.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184.89)">
<title>G</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-184.89 116.06,-184.89 116.06,4 -4,4"/>
<!-- a -->
<g id="node1" class="node">
<title>a</title>
<ellipse fill="yellow" stroke="black" cx="71.38" cy="-163.22" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="71.38" y="-159.52" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<ellipse fill="yellow" stroke="black" cx="18.38" cy="-91.15" rx="16.94" ry="16.94"/>
<text text-anchor="middle" x="18.38" y="-87.45" font-family="Times,serif" font-size="14.00">c</text>
</g>
<!-- a&#45;&#45;c -->
<g id="edge1" class="edge">
<title>a&#45;&#45;c</title>
<path fill="none" stroke="black" d="M61.17,-148.71C51.66,-136.14 37.59,-117.55 28.21,-105.15"/>
</g>
<!-- d -->
<g id="node4" class="node">
<title>d</title>
<ellipse fill="lightgrey" stroke="black" cx="71.38" cy="-91.15" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="71.38" y="-87.45" font-family="Times,serif" font-size="14.00">d</text>
</g>
<!-- a&#45;&#45;d -->
<g id="edge5" class="edge">
<title>a&#45;&#45;d</title>
<path fill="none" stroke="black" d="M71.38,-145.26C71.38,-134.57 71.38,-120.78 71.38,-109.94"/>
</g>
<!-- e -->
<g id="node5" class="node">
<title>e</title>
<ellipse fill="yellow" stroke="black" cx="94.38" cy="-18.38" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="94.38" y="-14.68" font-family="Times,serif" font-size="14.00">e</text>
</g>
<!-- a&#45;&#45;e -->
<g id="edge4" class="edge">
<title>a&#45;&#45;e</title>
<path fill="none" stroke="black" d="M80.91,-148.19C87.25,-137.97 95.01,-123.52 98.38,-109.54 104.45,-84.41 101.03,-54.22 97.84,-35.94"/>
</g>
<!-- b -->
<g id="node2" class="node">
<title>b</title>
<ellipse fill="lightgrey" stroke="black" cx="18.38" cy="-18.38" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="18.38" y="-14.68" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- c&#45;&#45;b -->
<g id="edge2" class="edge">
<title>c&#45;&#45;b</title>
<path fill="none" stroke="black" d="M18.38,-74.1C18.38,-63 18.38,-48.26 18.38,-36.87"/>
</g>
<!-- d&#45;&#45;e -->
<g id="edge3" class="edge">
<title>d&#45;&#45;e</title>
<path fill="none" stroke="black" d="M76.84,-73.38C80.55,-61.94 85.45,-46.86 89.13,-35.55"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.42.4 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="120pt" height="189pt"
viewBox="0.00 0.00 120.06 188.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184.89)">
<title>G</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-184.89 116.06,-184.89 116.06,4 -4,4"/>
<!-- a -->
<g id="node1" class="node">
<title>a</title>
<ellipse fill="lightgrey" stroke="black" cx="71.38" cy="-163.22" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="71.38" y="-159.52" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<ellipse fill="lightgrey" stroke="black" cx="18.38" cy="-91.15" rx="16.94" ry="16.94"/>
<text text-anchor="middle" x="18.38" y="-87.45" font-family="Times,serif" font-size="14.00">c</text>
</g>
<!-- a&#45;&#45;c -->
<g id="edge1" class="edge">
<title>a&#45;&#45;c</title>
<path fill="none" stroke="black" d="M61.17,-148.71C51.66,-136.14 37.59,-117.55 28.21,-105.15"/>
</g>
<!-- d -->
<g id="node4" class="node">
<title>d</title>
<ellipse fill="lightgrey" stroke="black" cx="71.38" cy="-91.15" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="71.38" y="-87.45" font-family="Times,serif" font-size="14.00">d</text>
</g>
<!-- a&#45;&#45;d -->
<g id="edge5" class="edge">
<title>a&#45;&#45;d</title>
<path fill="none" stroke="black" d="M71.38,-145.26C71.38,-134.57 71.38,-120.78 71.38,-109.94"/>
</g>
<!-- e -->
<g id="node5" class="node">
<title>e</title>
<ellipse fill="lightgrey" stroke="black" cx="94.38" cy="-18.38" rx="17.86" ry="17.86"/>
<text text-anchor="middle" x="94.38" y="-14.68" font-family="Times,serif" font-size="14.00">e</text>
</g>
<!-- a&#45;&#45;e -->
<g id="edge4" class="edge">
<title>a&#45;&#45;e</title>
<path fill="none" stroke="black" d="M80.91,-148.19C87.25,-137.97 95.01,-123.52 98.38,-109.54 104.45,-84.41 101.03,-54.22 97.84,-35.94"/>
</g>
<!-- b -->
<g id="node2" class="node">
<title>b</title>
<ellipse fill="lightgrey" stroke="black" cx="18.38" cy="-18.38" rx="18.27" ry="18.27"/>
<text text-anchor="middle" x="18.38" y="-14.68" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- c&#45;&#45;b -->
<g id="edge2" class="edge">
<title>c&#45;&#45;b</title>
<path fill="none" stroke="black" d="M18.38,-74.1C18.38,-63 18.38,-48.26 18.38,-36.87"/>
</g>
<!-- d&#45;&#45;e -->
<g id="edge3" class="edge">
<title>d&#45;&#45;e</title>
<path fill="none" stroke="black" d="M76.84,-73.38C80.55,-61.94 85.45,-46.86 89.13,-35.55"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,2 +1,2 @@
#!/usr/bin/env bash
rsync -avzu --delete ./public/ root@samuel.ortion.fr:/var/www/blog.samuel.ortion.fr/
rsync -avzu --delete ./public/ sortion@samuel.ortion.fr:/var/www/blog.samuel.ortion.fr/

@ -1 +1 @@
Subproject commit 77fdac90ad06d76c8e5b42db74fc2cfbb513e185
Subproject commit 2b9c7350f28fb803fdfab6d2bec510cefa35d2fd