Module 7 · Section 7.1
Cadrage et jeu de données
55 min · niveau intermediaire · dernière révision : 2026-11-01
Objectifs d'apprentissage
- Traduire une question biologique en question analysable, avec unité statistique et contraste explicites
- Construire un tableau de métadonnées validé et une matrice de design reproductible
- Choisir un jeu de données adapté et documenter sa provenance, sa licence et ses empreintes
- Rédiger un plan d'analyse avec contrôles qualité, risques et critères d'arrêt
- Concevoir la charte d'un projet intégré variants et expression sans confondre plan et résultat
Prérequis : 0.1 Introduction et reproductibilité, 3.1 Contrôle qualité NGS
Git 2.40+conda 24.x
Prérequis
Cette section s'appuie sur la section 0.1, qui introduit le cycle de vie d'un projet et la distinction entre données brutes et résultats dérivés, ainsi que sur la section 3.1, qui fixe les principes du contrôle qualité des lectures. Il est utile de savoir lire un fichier FASTQ, un VCF et un tableau de comptages, mais aucun pipeline complet n'est requis. Git et conda suffisent pour les exemples ; nous ne supposons aucune connaissance préalable de Snakemake ou de Nextflow.
Introduction
Une question biologique semble souvent tenir en une phrase : « le variant que nous venons d'observer modifie-t-il l'expression des gènes voisins ? » Derrière cette phrase se cachent pourtant des décisions qui déterminent tout le résultat. De quel organisme parle-t-on, et dans quelles conditions de culture ? Le variant est-il présent dans un clone isolé ou dans une population hétérogène ? L'expression est-elle mesurée au même moment, avec le même protocole, sur des réplicats biologiques indépendants ? Quel transcrit sert de référence, et quelle version du génome définit les coordonnées ? Sans réponses explicites, deux équipes peuvent produire des tableaux différents à partir des mêmes fichiers et croire qu'elles se contredisent.
Le défi computationnel est tout aussi concret. Les données arrivent sous forme de lectures FASTQ, de génomes de référence FASTA, d'annotations GFF ou GTF, de fichiers de variants VCF et de tableaux de métadonnées. Les traitements intermédiaires sont nombreux, et une modification silencieuse d'un seuil ou d'une accession suffit à rendre un résultat incomparable.
Le cadrage est ce travail d'anticipation. Il transforme une intention biologique en plan analysable : une unité statistique, un facteur, un contraste, des réplicats, des métadonnées validées, des contrôles qualité et des critères d'arrêt. Il distingue aussi ce qui est planifié de ce qui sera exploratoire. Cette section propose une méthode et quatre fonctions Python pour rendre ce cadrage vérifiable, puis une étude de cas de projet intégré « variants + expression » sur un jeu unique.
Théorie
De la question biologique à l'unité d'analyse
Une question biologique décrit un phénomène ; une question analysable précise une comparaison, une mesure et une population. « Le variant modifie-t-il l'expression ? » devient : « chez Escherichia coli K-12 cultivé dans les mêmes conditions, l'expression normalisée du gène cible diffère-t-elle entre les clones mutants et les clones de référence ? » Elle fixe l'organisme, la condition, la réponse, le facteur et l'unité d'observation ; le prélèvement et la mesure restent à discuter.
L'unité statistique est l'entité indépendante observée. En transcriptomique en vrac (bulk RNA-Seq), c'est l'échantillon biologique, pas la lecture ni le gène ; en génomique, c'est l'individu, le clone ou la culture. Trois tubes issus d'une même culture sont des réplicats techniques, pas biologiques : ils mesurent la variabilité de préparation. Les traiter comme trois réplicats biologiques est une pseudo-réplication, qui rétrécit artificiellement les intervalles de confiance.
Le modèle le plus simple s'écrit
où est la réponse de l'échantillon du groupe , une moyenne de référence, l'effet du niveau et un résidu. Ce modèle résume une hypothèse sur la variabilité ; les résidus ne doivent pas cacher un lot, une dérive de culture ou une profondeur inégale. Le nombre de réplicats dépend de la variance attendue, de l'effet à détecter et du budget. L'erreur standard diminue avec , sans corriger un biais de conception.
Variables, contrastes et matrice de design
Le modèle linéaire s'écrit sous forme matricielle
où contient les observations, est la matrice de design de taille , les coefficients et les résidus. Chaque ligne décrit un échantillon, chaque colonne un paramètre. Avec un facteur à deux niveaux, le codage de traitement combine un intercept et une indicatrice pour le niveau non référence. Si « contrôle » est la référence, la colonne « traité » vaut 1 pour les traités et 0 sinon ; le coefficient associé n'est pas la moyenne des traités, mais la différence traité moins contrôle.
Un contraste est une combinaison linéaire de coefficients, notée . Pour comparer traité et contrôle, et l'effet vaut . Cette écriture explicite la comparaison et vérifie l'identifiabilité : si une colonne de est combinaison linéaire des autres, la matrice n'est pas de rang plein. Si tous les contrôles sont au lot 1 et tous les traités au lot 2, l'indicatrice de traitement et celle de lot sont identiques, et aucun logiciel ne peut séparer les deux effets.
La construction de coûte en temps et en mémoire, la validation des métadonnées pour colonnes requises. La matrice fixe ce qui sera estimé ; un facteur oublié ne se rattrape pas.
Choisir le matériel : génome, transcriptome, données synthétiques
Le fil rouge du cours est le génome d'E. coli K-12 MG1655, accession NC_000913.3. Cette accession complète définit les coordonnées et les annotations compatibles. Écrire « E. coli K-12 » sans version ne suffit pas. Si le FASTA de référence et le GFF utilisé pour annoter les variants ne partagent pas la même version, les positions peuvent être décalées et un variant associé au mauvais gène. Il faut donc figer le FASTA, le GFF, l'index de l'aligneur et la version de l'outil d'appel.
Le jeu airway de Bioconductor fournit un transcriptome humain de cellules musculaires lisses des voies aériennes. Il est adapté à l'analyse différentielle, mais pas à un projet intégré de variants génomiques : ce sont des données d'expression, pas des génomes appariés. Le jeu est public, mais il faut vérifier sa licence et sa provenance ; des données humaines publiques ne doivent pas être réidentifiées.
Les jeux synthétiques du dossier datasets/ servent à tester les pipelines. Ils sont étiquetés comme tels et ne permettent aucune conclusion biologique. Ils fournissent une vérité terrain, mais un pipeline validé sur du synthétique ne l'est pas nécessairement sur des données réelles.
Pour un projet intégré, la règle est de partir d'un jeu unique et cohérent. Deux jeux publics aux protocoles et profondeurs différents ne se recollent pas sans table de correspondance. Mieux vaut un seul jeu, avec deux modalités issues des mêmes échantillons.
Métadonnées, contrôle qualité et intégrité
Un tableau de métadonnées contient une ligne par échantillon et une colonne par variable. Les noms sont stables et en anglais, les valeurs contrôlées, les dates ISO, les chemins relatifs. L'identifiant est écrit dans sample_id, jamais déduit du nom de fichier.
Un jeu de variants et d'expression comprend typiquement sample_id, condition, replicate, batch, les chemins des fichiers et la version de la référence. La validation est stricte : colonne absente, valeur vide, identifiant dupliqué, niveau manquant. Une valeur None ou une chaîne d'espaces est manquante, pas une catégorie. Le contrôle échoue avant l'analyse en indiquant la ligne et la colonne.
Le contrôle qualité couvre adaptateurs, duplication, contamination, mapping, couverture, taille de bibliothèque, concordance et valeurs aberrantes. Les seuils sont fixés avant l'analyse ; un échantillon qui échoue est discuté, pas supprimé silencieusement. Une analyse en composantes principales repère un lot ou un échantillon inversé ; pour les variants, la couverture et la qualité des appels sont déterminantes.
L'intégrité se vérifie par , consigné avec le chemin, la taille et une empreinte du manifeste. Une empreinte détecte une corruption ou un transfert incomplet ; elle ne prouve ni l'authenticité, ni la validité biologique. Les données brutes sont immuables : on crée un fichier filtré dans un dossier dérivé. Le dépôt distingue raw/, reference/, metadata/, results/, scripts/ et reports/ ; un résultat doit être régénérable à partir des entrées, du code et de l'environnement.
Plan d'analyse, risques et critères d'arrêt
Un plan d'analyse décrit l'analyse principale, les analyses secondaires, le modèle, les covariables, le seuil, la correction pour tests multiples et les analyses de sensibilité. Pour un projet transcriptomique, l'analyse principale peut être un modèle DESeq2 avec le facteur biologique et, si nécessaire, le lot. Pour un projet de variants, elle précise les filtres de qualité, la profondeur minimale et l'annotation. Les tests multiples sont corrigés par Benjamini-Hochberg, qui contrôle le taux de fausses découvertes ; seuil et méthode sont annoncés avant de regarder les résultats.
Les risques se documentent, car ils orientent les contrôles : inversion d'échantillons entre modalités, confusion entre condition et lot, profondeur insuffisante, dérive de version et licence incompatible. Chacun a sa parade : table de correspondance, randomisation équilibrée, seuil de couverture, environnement verrouillé, vérification juridique. Les critères d'arrêt sont explicites : identité non résolue, taux de mapping sous le seuil, plus de réplicat utilisable ou licence interdisant l'analyse. Un critère d'arrêt protège contre un résultat faux. Un journal versionné note la date, la décision, la raison et la personne responsable.
Exemple travaillé à la main
Six échantillons, trois contrôles et trois traités, avec sample_id, condition et batch. Les niveaux de condition sont triés : control puis treated. La référence est control, et la matrice de design a deux colonnes : l'intercept et l'indicatrice treated.
| Échantillon | Condition | Lot | Intercept | Traité |
|---|---|---|---|---|
| C1 | control | B1 | 1 | 0 |
| C2 | control | B2 | 1 | 0 |
| C3 | control | B1 | 1 | 0 |
| T1 | treated | B2 | 1 | 1 |
| T2 | treated | B1 | 1 | 1 |
| T3 | treated | B2 | 1 | 1 |
Le contraste traité moins contrôle vaut et son effet estimé est . Si les lots sont équilibrés entre les conditions, le modèle peut inclure le lot comme covariable et séparer les deux effets. Si, au contraire, tous les contrôles sont en B1 et tous les traités en B2, la colonne batch devient identique à la colonne treated : la matrice perd un rang et aucun coefficient n'est estimable séparément. La conclusion correcte n'est pas « le traitement a un effet » mais « le traitement et le lot sont confondus, le plan ne permet pas de conclure ».
Implémentation
Les fonctions de cette section sont sans dépendance externe. Elles s'exécutent avec Python 3.11+, conda 24.x et Git 2.40+. L'objectif n'est pas de remplacer pandas, mais de rendre les règles de validation explicites et testables.
La première fonction valide un tableau de métadonnées. Elle renvoie un rapport plutôt que de lever une exception pour une erreur de données, afin d'accumuler les problèmes. Les types invalides lèvent une exception, car ils traduisent un bug d'appel.
Aucune sortie. Exécutez le code pour voir le résultat.
Le code s'exécute dans votre navigateur (Web Worker isolé). Il n'a pas accès au serveur ; l'accès réseau est désactivé pendant l'exécution. Le premier clic sur « Exécuter » télécharge Pyodide depuis jsDelivr (plusieurs mégaoctets, version 0.26.4 épinglée) ; rien n'est chargé avant ce clic.
La sortie vérifiée le 2026-11-01 confirme valid: True, trois lignes, aucun doublon, et la matrice [[1, 0], [1, 0], [1, 1]] avec control comme référence. Le tri des niveaux rend la référence déterministe. La normalisation des espaces autour de sample_id signale S01 et S01 comme le même identifiant.
La deuxième fonction calcule un manifeste SHA-256, trié par chemin pour rendre l'empreinte globale stable.
import hashlib
import os
def checksum_manifest(files):
if isinstance(files, dict):
entries = list(files.items())
else:
entries = []
for item in files:
if isinstance(item, dict):
entries.append((item["path"], item.get("content")))
else:
entries.append((item, None))
manifest = []
seen = set()
for path, content in entries:
path = os.fspath(path)
if path in seen:
raise ValueError("duplicate path: " + path)
seen.add(path)
if content is None:
with open(path, "rb") as handle:
data = handle.read()
elif isinstance(content, str):
data = content.encode("utf-8")
else:
data = bytes(content)
manifest.append({
"path": path,
"size_bytes": len(data),
"sha256": hashlib.sha256(data).hexdigest(),
})
manifest.sort(key=lambda entry: entry["path"])
canonical = "".join(entry["sha256"] + " " + entry["path"] + "\n" for entry in manifest)
return {
"algorithm": "sha256",
"n_files": len(manifest),
"entries": manifest,
"total_bytes": sum(entry["size_bytes"] for entry in manifest),
"manifest_sha256": hashlib.sha256(canonical.encode("utf-8")).hexdigest(),
}Pour figer l'environnement, on exporte les dépendances et on tague le commit du plan. Les commandes suivantes supposent un dépôt Git initialisé.
conda env export --from-history > environment.yml
git add environment.yml metadata/ scripts/
git commit -m "Cadrage 7.1 : metadonnees, environnement et plan"
git tag -a analyse-v1 -m "Plan d'analyse fige avant execution"
sha256sum -c metadata/checksums.sha256Sous Windows, Git Bash fournit sha256sum et PowerShell propose Get-FileHash -Algorithm SHA256. L'important est le contrôle avant et après le transfert.
Étude de cas
Nous concevons la charte d'un projet intégré sur un jeu unique de formation, ecoli-integratif-demo, explicitement synthétique. Il n'est pas distribué dans datasets/ et ne doit pas être présenté comme une mesure réelle. Aucun résultat numérique n'est annoncé : les sorties seront produites par l'étudiant, puis comparées au plan.
Le jeu contient huit clones d'E. coli K-12, quatre de référence et quatre mutants, avec deux modalités par clone : lectures génomiques et transcriptomiques. Les lots sont équilibrés. Chaque clone a un identifiant stable, un réplicat et les chemins de ses quatre FASTQ ; le tableau de métadonnées est la seule source de vérité.
| Fichier d'entrée | Rôle | Contrôle attendu |
|---|---|---|
reference/NC_000913.3.fasta | génome de référence | accession et empreinte |
reference/NC_000913.3.gff3 | annotation | version compatible avec le FASTA |
metadata/metadata.tsv | une ligne par clone | validation des colonnes et des identifiants |
raw/genome/S01_R1.fastq.gz et R2 | lectures génomiques | qualité, adaptateurs, mapping |
raw/rnaseq/S01_R1.fastq.gz et R2 | lectures transcriptomiques | qualité, rRNA, taille de bibliothèque |
metadata/checksums.sha256 | manifeste | vérification avant analyse |
env/environment.yml | versions des outils | reconstruction de l'environnement |
workflow/Snakefile | ordonnancement | reproductibilité des étapes |
La question est : « le variant candidat modifie-t-il l'expression des gènes voisins, et le signal transcriptomique est-il cohérent avec le génotype ? » Le contraste principal est condition: mutant vs reference, complété par une comparaison des variants. L'unité statistique est le clone, avec quatre réplicats par groupe ; le lot reste une covariable à tester.
Six étapes : valider métadonnées et empreintes ; contrôler les deux modalités et consigner les exclusions ; mapper sur NC_000913.3, appeler, filtrer et annoter les variants ; quantifier l'expression, normaliser et ajuster un modèle différentiel avec le facteur biologique et, si possible, le lot ; joindre variants et expression par gène ; produire un rapport séparant tests planifiés et observations exploratoires.
| Sortie attendue | Contenu | Interprétation autorisée |
|---|---|---|
results/qc/multiqc_report.html | qualité des lectures et du mapping | décider des exclusions selon les seuils fixés |
results/variants/filtered.vcf.gz | variants filtrés et annotés | décrire le génotype observé, avec les limites de l'appel |
results/expression/counts.tsv | comptages par gène et par échantillon | matrice d'expression, pas encore un effet biologique |
results/expression/deseq2_results.tsv | estimés, erreurs, valeurs ajustées | comparer mutant et référence pour chaque gène |
results/integration/variant_expression.tsv | jointure variant-gène-expression | formuler une hypothèse, pas une causalité |
reports/final_report.html | méthodes, versions, limites | rendre le travail vérifiable |
L'interprétation reste prudente : une association n'établit pas la causalité, le variant peut être en déséquilibre avec un autre changement ou accompagné d'un effet de construction. Un résultat négatif est informatif si la puissance et la qualité suffisent. Le transcriptome mesure un état stationnaire, et l'appel sur lectures bulk peut manquer un variant rare. La jointure dépend de l'annotation : un variant intergénique n'a pas de gène cible évident.
Les risques sont l'inversion de fichiers entre modalités, la confusion condition-lot, la dérive d'annotation et un seuil de couverture trop permissif. Les critères d'arrêt sont l'identité non résolue, un mapping sous le seuil, une couverture insuffisante, aucun réplicat utilisable ou une licence incompatible.
Le jeu étant synthétique, il n'y a aucune donnée personnelle et les fichiers créés sont sous CC0 1.0. Le génome de référence est public, mais sa notice NCBI doit être conservée. Avec le transcriptome airway, il faudrait vérifier la licence, ne pas réidentifier les donneurs et ne pas diffuser de dérivés sans autorisation. Licence du code et licence des données sont distinctes.
Erreurs fréquentes
Quiz
Exercices
Énoncé
Implémenter validate_metadata(rows, required_columns) et design_matrix(metadata, factor). La validation renvoie valid, n_rows, columns, required_columns, missing_columns, missing_values, duplicate_sample_ids et errors, avec les codes empty_table, missing_column, missing_value et duplicate_sample_id. Une valeur None ou une chaîne d'espaces est manquante. La matrice trie les niveaux, prend le premier comme référence, ajoute un intercept et une indicatrice par niveau non référence, et renvoie factor, reference, levels, columns, matrix, sample_ids, level_counts et balanced. Aucune entrée n'est modifiée.
Comment vérifier votre travail
Les tests se trouvent dans exercises/module-7/7.1-cadrage-jeu-de-donnees/test_7_1.py. Depuis la racine du dépôt :
python -m pytest exercises/module-7/7.1-cadrage-jeu-de-donnees -qCorrigé verrouillé
Le corrigé est chargé uniquement après confirmation. Il n'est pas présent dans la page avant cette action.
Énoncé
Implémenter analysis_plan(question) et checksum_manifest(files). Le plan classe la question en integrative, differential_expression, variant_calling ou exploratory par mots-clés, puis renvoie types de données, contrastes, étapes, contrôles qualité, unité statistique, réplicats minimaux, correction de tests, risques, critères d'arrêt et livrables, sans aucun résultat. Le manifeste accepte un dictionnaire {chemin: contenu} ou des entrées {"path", "content"} ou des chemins, trie par chemin et renvoie algorithm, n_files, entries, total_bytes et manifest_sha256. Un chemin dupliqué lève ValueError.
Comment vérifier votre travail
Les tests se trouvent dans exercises/module-7/7.1-cadrage-jeu-de-donnees/test_7_1.py. Depuis la racine du dépôt :
python -m pytest exercises/module-7/7.1-cadrage-jeu-de-donnees -qCorrigé verrouillé
Le corrigé est chargé uniquement après confirmation. Il n'est pas présent dans la page avant cette action.
Énoncé
Mini-projet : charte d'un projet intégré. Implémenter project_charter(question, metadata). La fonction valide une question et un tableau non vides, détecte le facteur parmi condition, group, treatment et genotype, vérifie sample_id, les doublons, les valeurs manquantes, les niveaux et les réplicats par groupe. Elle renvoie valid, errors, warnings, n_samples, factor, design, question_type, data_types, contrasts, analyses, deliverables, risks, stop_criteria et metadata_summary. Un groupe d'un échantillon est une erreur ; deux produisent un avertissement. La charte ne calcule aucun résultat et ne modifie pas les entrées.
Comment vérifier votre travail
Les tests se trouvent dans exercises/module-7/7.1-cadrage-jeu-de-donnees/projet/test_projet_7_1.py. Depuis la racine du dépôt :
python -m pytest exercises/module-7/7.1-cadrage-jeu-de-donnees/projet -qCorrigé verrouillé
Le corrigé est chargé uniquement après confirmation. Il n'est pas présent dans la page avant cette action.
Résumé
- Une question analysable fixe unité, réponse, facteur, contraste et population.
- Le design précède l'analyse : matrice, référence explicite, vérification du rang.
- Les réplicats biologiques sont indépendants ; les techniques ne les remplacent pas.
- Les métadonnées sont un contrat tabulé, validé avant toute jointure.
- Les checksums SHA-256 détectent les corruptions, pas l'invalidité biologique.
- Le plan annonce tests, covariables, correction multiple, risques et critères d'arrêt.
- Un projet intégré repose sur un jeu unique, deux modalités, les mêmes identifiants.
- La reproductibilité fige versions, accessions, environnement et décisions.
Références
- The Turing Way Community (2022). The Turing Way: A handbook for reproducible, ethical and collaborative data science. https://the-turing-way.netlify.app/
- Mölder, F. et al. (2021). Sustainable data analysis with Snakemake. F1000Research, 10, 33.
- Di Tommaso, P. et al. (2017). Nextflow enables reproducible computational workflows. Nature Biotechnology, 35(4), 316–319.
- NCBI RefSeq. Escherichia coli str. K-12 substr. MG1655, accession NC_000913.3. https://www.ncbi.nlm.nih.gov/nuccore/NC_000913.3
- Bioconductor. airway: RNA-Seq of human airway smooth muscle cells. https://bioconductor.org/packages/airway/
- NCBI. E-utilities documentation. https://www.ncbi.nlm.nih.gov/books/NBK25501/