
En bioinformatique, quand on manipule des génomes, des annotations, des fichiers d’alignement, des variants ou des intervalles (exons, régions régulatrices, etc.), on est rapidement confronté à deux notions fondamentales qui conditionnent la manière dont les positions sont décrites et interprétées :
- le système d'indexation : commence-t-on à compter à 0 ou à 1 ? Certains formats adoptent une numérotation commençant à 0, comme dans de nombreux langages de programmation. D’autres optent pour une numérotation commençant à 1, plus intuitive car conforme à notre manière naturelle de compter.
- le type d’intervalle : les bornes sont-elles inclusives ou non ?
Chaque intervalle possède un début et une fin, mais ces bornes peuvent être incluses ou exclues. On peut ainsi représenter les régions à l’aide d’intervalles « inclusif-inclusif », « inclusif-exclusif », « exclusif-inclusif » ou « exclusif-exclusif ».
Ces deux dimensions définissent ensemble le système de coordonnées utilisé. Les maîtriser permet d’interpréter correctement les positions génomiques et de travailler sereinement avec des données hétérogènes. Dans cet article, nous allons présenter clairement ces systèmes de coordonnées et, je l’espère, vous aider à déjouer les pièges les plus courants.
Creusons maintenant ces deux concepts plus en détail.
Le système d'indexation
Avant d’aborder les systèmes de coordonnées utilisés en génomique, il est utile de faire un détour par l’informatique. En programmation, l’indexation désigne la manière dont on numérote les éléments d’une structure ordonnée, comme un tableau ou une chaîne de caractères. Deux conventions principales existent : l’indexation 0-based et la 1-based.
Indexation 0-based
Dans une indexation 0-based, le premier élément est numéroté 0, le second 1, et ainsi de suite.
Cette convention est historiquement liée aux langages de bas niveau, notamment C, où l’accès à un élément d’un tableau se fait par calcul d’un décalage (offset) par rapport à l’adresse mémoire de base. La première entrée est à zéro de l'origine du tableau, la deuxième entrée est à un décalage de 1. Ce lien direct entre index et décalage rend l’indexation 0-based très naturelle pour les machines et a influencé de nombreux langages modernes, comme Python, Java, C++, etc.
Indexation 1-based
À l’inverse, l’indexation 1-based numérote le premier élément 1, le deuxième 2, etc.
Elle est plus intuitive pour l’humain puisqu’elle s’aligne avec notre manière naturelle de compter : le premier élément est “1ᵉʳ”, pas “0ᵉ”.
Cette convention est utilisée dans des langages comme R, Fortran, MATLAB, ou encore dans certaines interfaces orientées utilisateurs.
Ces deux traditions d'indexation, le 0-based issu de l'informatique et le 1-based hérité des usages humains et mathématiques, se retrouvent aujourd’hui dans les formats génomiques.
Ainsi, certains fichiers utilisent le 0-based comme le format BED ou BAM, tandis que d’autres reposent sur le 1-based comme le GFF/GTF ou SAM. Les langages de programmation reflètent la même diversité. D’où l’importance d'identifier clairement le système d'indexation employé par les formats que l’on manipule ainsi que par les outils ou langages avec lesquels on travaille.

Notion d’intervalles ouverts / fermés
Au-delà du choix de l’indexation (0-based ou 1-based), la façon dont on inclut ou exclut les bornes d’un intervalle joue un rôle crucial dans la représentation des régions génomiques.
Cette notion, issue des mathématiques, permet de préciser si les positions de début et de fin appartiennent ou non à la région décrite. On distingue les bornes fermés qui sont inclus dans l'intervalle noté par des crochets "[]" et les bornes ouvertes noté par des parenthèses "()". Ce qui nous donne un total de 4 possibilités : fermé-fermé, fermé-ouvert, ouvert-fermé, ouvert-ouvert.

Regardons maintenant ensemble, plus en détails, ces quatre types d'intervalles.
Intervalles avec début exclusif (a, b] et (a,b)
En mathématique ou statistique où l'on rencontre souvent des valeurs continues il est possible de rencontrer ces usages. Mais les positions génomique correspondent à des entités discrètes… une base existe à une position entière ! Exclure une base « en amont » n'est pas vraiment pratique. Exclure aussi la fin devient vraiment bizarre, l'intervalle perd ses repères naturels et nous aussi par l'occasion. Quid de l'exclusion uniquement de la base « en aval » [a, b) ? On va voir plus loin que cette dernière à finalement de bonnes raisons d'exister.
Intervalle fermé [a, b]
Il correspond à la manière “naturelle” de compter chez l’humain :
si l’on dit qu’une région commence à la position 5 et se termine à 7, on inclut les positions 5, 6 et 7 donc 3 bases. C’est pourquoi ce modèle est utilisé dans des formats génomiques orientés annotation humaine, comme GFF/GTF, SAM ou VCF.
Mais ce choix intuitif devient moins pratique dès qu’on souhaite calculer une longueur ou manipuler des régions en programmation.
Pour la longueur, il faut penser à ajouter +1 :
|
1 2 3 |
start = 5 end = 7 longueur = 7 - 5 + 1 = 3 |
Pour la manipulation programmatique, l’intervalle fermé-fermé ne s’aligne pas avec le "slicing", la convention la plus répandue en informatique pour accéder à une portion d’un tableau ou d’une chaîne de caractères.
Dans la majorité des langages, que l’on dispose d’un slicing natif (Python) ou de fonctions dédiées (Java, JavaScript, C++), les sous-séquences sont définies selon un modèle semi-ouvert : inclure l’index de début, exclure l’index de fin, c’est-à-dire un intervalle de type [start, end). (Dans le cas de C++ on spécifie un début + une longueur, ce qui aboutit aussi à un comportement compatible avec un intervalle semi-ouvert).
Il existe des exceptions, comme R, qui adopte une logique inclusive (x[1:5] renvoie les positions 1 à 5). Mais la convention dominante dans la plupart des langages reste l’intervalle semi-ouvert. Voir l'antisèche plus loin pour voir les "exceptions".
Avec un intervalle fermé-fermé [a, b], extraire la région correspondante dans ces langages impose donc un ajustement de la borne de fin :
pour inclure b, il faut aller jusqu’à b+1 :
|
1 |
s[a : b+1] |
Autrement dit, une borne droite « fermée » dans les formats humains doit être convertie en borne « ouverte » dans les fonctions d’extraction, ce qui introduit une étape mentale supplémentaire… et une source classique d’erreurs.
Intervalle semi-ouvert [a, b)
Ici, la borne de début "a" est incluse, mais la borne de fin "b" est exclue. Ce modèle utilisé dans des formats comme BED ou BAM peut sembler contre-intuitif au premier abord, mais il simplifie énormément les opérations.
La longueur devient simplement :
|
1 |
longueur = b - a |
Le chaînage d’intervalles contigus se fait naturellement :
|
1 |
[4, 7) puis [7, 10) |
Le premier s’arrête À 7 (exclue), le second commence À 7 (inclus), aucune base ne se chevauche.
Et surtout, il est parfaitement aligné avec la logique des slices utilisés en programmation. Extraire [a, b) revient simplement à écrire (e.g. python):
|
1 |
s[a:b] |
sans aucune transformation, ni +1, ni -1.
Les deux systèmes de coordonnées utilisés en bioinformatique
Si l’on combine les deux types d’indexation (0-based, 1-based) et les quatre types d’intervalles (fermés, ouverts, les deux semi-ouvertes), on obtient 8 systèmes de coordonnés possibles. Sur ces 8 possibilités toutes ne sont pas utilisés en bioinformatique, heureusement ! Seules deux formes d'intervalles sont réellement utilisées. Mais quelle sont-elle ? Et Pourquoi ? Je sais vous trépignez d'impatience de savoir le fin mot de l'histoire, on y arrive doucement.
On peut commencer par écarter les intervalles dont la borne de début est ouverte comme (a,b] et (a,b) car que ce soit en 0-based ou 1-based, les arguments avancé dans le paragraphe précédent reste entier. Exclure le premier élément d'un intervalle est pas un choix agréable pour la logique humaine. Ca n'aide pas à s'encrer dans l'espace du réel. Les positions que nous cherchons à manipuler sont des entités discrètes, pas des valeurs continues. ll n’y a donc aucun sens biologique à exclure arbitrairement la première "base" d’une région. S'il n'y a pas de raisons valables ou une logique à laquelle se raccrocher pour imposer quelque chose de peu intuitif pourquoi s'embêter…
Le 1-based fermé-fermé [a, b] suit la logique intuitive humaine : on compte à partir de 1 et on inclut naturellement les deux bornes. Utiliser le 0-based fermé-fermé [a, b] est contre-intuitif, il mélange la logique informatique et la logique humaine. De plus, les gains dans la simplification de calcul de longueur et d'extraction sont perdus. Pour la longueur il faudrait faire end - start + 1 au lieu de end - start. Et pour l'extraction de région il faudrait faire s[a : b+1] au lieu de s[a : b].
Le système de d'indexation 0-based provient d'une logique informatique. Associé au type d'intervalle semi-ouvert [a,b), il devient fort pratique. Il suit pleinement les concepts informatique en s'alignant sur les principes de slicing ,et simplifie les calculs. En ce sens l'utilisation 1-based semi-ouvert [a, b) semble être une aberration. Il mélange la logiques humaine du 1-based et la logique informatique du semi-ouvert. En combinant les deux mondes, finalement on annule les avantages des deux. Il n'est ni intuitif : [1,100) : la longueur ferait 99 bases ; ni pratique du fait de son éloignement du concept informatique du slicing : pour l'extraction d'une région il faudrait faire s[start -1 : end -1] à la place de s[start - 1 : end]. A la rigueur le seul point qui serait simplifié serait le calcul de la longueur d'une région qui serait end - start. Mais il semblerait que ca n'ai pas était suffisant pour garder cette approche.
Au final seuls deux systèmes de coordonnés sont utilisés en pratique :
le 1-based fermé-fermé [a, b] et le 0-based semi-ouvert [a, b). Ce n’est pas un hasard : ce sont les deux seuls couples qui conservent une logique cohérente dans leur domaine d’origine.

Conclusion
La coexistence des différents systèmes de coordonnées en génomique n’est pas le fruit du hasard : elle découle d’héritages historiques et de logiques pratiques.
Du côté informatique, les premiers langages de bas niveau ont popularisé l’indexation 0-based, car elle correspond directement au calcul d’un décalage en mémoire (offset). Cette approche s’est ensuite naturellement combinée avec le modèle d’intervalle half-open [start, end), très pratique pour raisonner en termes de slices, calculer des longueurs (end − start) ou concaténer des segments sans ambiguïté. C’est pourquoi de nombreux formats bioinformatiques manipulés par des outils programmatiques, comme BED, utilisent cette convention.
En parallèle, une autre tradition s’est imposée : celle du 1-based fully closed [start, end]. Plus intuitive pour l’esprit humain, elle correspond à la manière dont nous comptons naturellement les positions (« la première base est la 1ᵉ »), et facilite la lecture directe d’annotations génomiques. Ce modèle est dominant dans les formats plus orientés « biologie », tels que GFF/GTF ou VCF, souvent utilisés comme interfaces entre spécialistes humains.
Ainsi, la bioinformatique se situe à la rencontre de deux cultures :
• l’une, informatique, optimisée pour les calculs et la manipulation algorithmique,
• l’autre, biologique, tournée vers l’interprétation humaine.
Aucune convention n’est intrinsèquement meilleure : chacune répond à une logique différente. L’essentiel est d’être conscient de ces choix, de les documenter clairement, et de manipuler les conversions avec soin pour éviter les erreurs de type « off-by-one ». En comprenant l’origine de ces systèmes et leurs implications, on peut mieux naviguer entre formats et outils, et garantir la fiabilité des analyses génomiques.
Il faut garder en tête que lorsqu’on utilise un format 1-based dans un langage ou une bibliothèque 0-based, il est nécessaire d’effectuer les conversions adéquates. Certaines librairies appliquent ces transformations automatiquement. Par exemple, le format SAM, défini en 1-based, est converti en 0-based lorsqu’il est manipulé via pysam. Cette automatisation est pratique, mais peut aussi devenir source d’erreur si l’on ignore qu’elle a lieu.
En résumé, maîtriser ces conventions et leurs conversions est un prérequis indispensable pour travailler sereinement avec les données génomiques.
Pour aller plus loin et comprendre l'implication des systèmes de coordonnés sur la description de variant je vous invite à regarder ceci :
https://juke34.github.io/coordinate_systems/variants
Un immense merci à Guillaume, Samuel et Azerin pour leur relecture attentive de l'article.
P.S : l'IA a été utilisé pour formater le texte et corriger les fautes d'orthographes.


Laisser un commentaire