Réunion 04/02/26

Lionel Viguier

Ordre du jour

  • Vous montrer mes jolis diapos
  • Présentation du travail sur l’issue 7
  • Partie discussion avec mes questions

issue_#7

Crée par Vincent dans le projet yapp_forked, elle consiste en la correction de petits bugs, et l’amélioration générale du code. Focus sur un des point:

variable = genotype[int(pednode.indiv)-1,...]

Probleme si pednode.indiv est un str.

Solution: créer des indexes.

  • l’indexe doit étre relatif a un individus
  • l’indexe doit référencer la bonne ligne du genotype_array

Plusieurs solutions envisager

Dictionnaire

  • facile a mettre en oeuvre
  • créer une nouvelle structure de donnée

Parametres idx dans PedNode

  • demande la modification de l’objet PedNode
  • pas de nouvelle structure de donnée

Solution choisie

Parametres idx -> on parcour le pedigree par individu.

Mise en place du parametres

version de add_indiv de Pedigree

def add_indiv(self, indiv):
    """Add a new guy to the pedigree"""
    if indiv in self.nodes:
        logger.debug(f"{indiv} is already there")
    else:
        self.nodes[indiv] = self.node_class(indiv)

version de add_indiv de PedigreePeel

# Overwrite
def add_indiv(self, indiv):
    """Add a new guy to the pedigree"""
    if indiv in self.nodes:
        logger.debug(f"{indiv} is already there")
    else:
        self.nodes[indiv] = self.node_class(indiv, self.__current_idx)
        self.__current_idx += 1
  • modification du constructeur de PedNodePeel

Intégration dans le pedigree

Lors de la création d’un pédiger chaque individu est ajouter a l’aide de la fonction add_indiv

@classmethod
def from_fam_file(cls, path, prt_from_FID=False, default_prt=MALE:
    [...]
    if rel[1] is not None:
        ped.set_father(rel[0], rel[1])
    if rel[2] is not None:
        ped.set_mother(rel[0], rel[2])
    if rel[1] is None and rel[2] is None:
        ped.add_indiv(rel[0])
    if rel[1] is not None and rel[2] is not None:
        ped.set_fam_peel(rel[1], rel[2], rel[0])
    _ = ped.nodes[rel[0]]
return ped

☑️ Créer un indexe relatif a chaque individus.

Faire le lien entre l’indexe et le génotypage

Il existe plusieurs type de fichier de génotypages. Deux fonction permette de lire différent type de fichier:

  • LoadGenotype a partir d’un .csv
  • ReadVCF qui lui utilise un fichier .vcf

LoadGenotype function

def LoadGenotypes(file: str, ped: PedigreePeel, sep: str = "\t", unknowGenotype=3) -> np.ndarray:
    with open(file, newline="") as csvfile:
        reader = csv.reader(csvfile, delimiter=sep)

        # Read the first row to initialise np array
        firstrow = next(reader)
        # Create np.array (nInd, nSNP) full of "unknowGenotype" int: 3 by default
        genotypes_array = np.full((len(ped.nodes), (len(firstrow) - 1)), unknowGenotype)
        try:
            genotypes_array[ped.nodes[firstrow[0]].idx, ...] = firstrow[1:] 
        except KeyError:
            print(row[0], "is missing in the pedigree: individual ignored")
        for row in reader:
            try:
                genotypes_array[ped.nodes[row[0]].idx, ...] = row[1:]
            except KeyError:
                print(row[0], "is missing in the pedigree: individual ignored")
    return genotypes_array
  • ajout de ped dans les parametres
  • gestion de l’absence de l’individu dans le pedigree avec try

ReadVCF function

def ReadVCF(vcfile: str, ped, mode: str = "likelihood", baseValue: float = 0.0) -> np.ndarray:
    samples = list(ped.nodes.keys())  # Try to remove list() when it's done
    vcfdat = vcf.vcf2fph(vcfile, samples=samples, mode=mode)
    assert mode in ["likelihood","genotype", ], "mode can only be likelihood or genotype."
    # vcfdat is organized per chromosome, so we need to merge them
    # Pre allocation table
    nInd, nLoci = len(samples), sum(
        [len(vcfdat["variants"][key]) for key in vcfdat["variants"].keys()]
    )
    if mode == "likelihood":
        genotypes = np.full((nLoci, 3, nInd), baseValue, dtype=np.float32)
    else:
        genotypes = np.full((nLoci, nInd), baseValue, dtype=np.int8)
    for chr in vcfdat["regions"]:
        for node in ped:
            try:
                genotypes[..., node.idx] = vcfdat["data"][chr][node.indiv]
            except KeyError:
                logger.warning(f"Individual {node.indiv} missing in vcf.")

    return genotypes
  • au lieu de prendre samples en parametres on prend un Pedigree puis on calcule samples.
  • on parcoure les node et on place le contenu du vcf dans l’array a l’emplacement indiqué par node.idx

Discussion

  1. ✏️ PedNode.idx <- une bonne idée?
  2. ⚠️ Si un individu est retirer du pédiger alors on a une “ligne morte” dans nos array
  3. Comment est construit un .vcf?
  4. En quoi consiste exactement l’issue 8 Export imputed genotypes to VCF
    • comment un .vcf stocke les likelihood?
    • peut-on faire un parser pour créer un .vcf?
  5. 📈 Comment paralléliser l’iterative Peeling?
  6. 📋 Trop tôt pour parler du Benchmark?

Perspectives

  • travailler sur l’issue 6 handle missing one parent in pedigree data.
  • travailler sur l’issue 8 Export imputed genotypes to VCF
  • regarder la pipeline lcWGS en vue de créer le Benchmark