mirror of
https://github.com/metabarcoding/obitools4.git
synced 2026-03-25 13:30:52 +00:00
Implémentation complète de la persistance pour FrequencyFilter
Ajout de la fonctionnalité de sauvegarde et de chargement pour FrequencyFilter en utilisant le KmerSetGroup sous-jacent. - Nouvelle méthode Save() pour enregistrer le filtre dans un répertoire avec formatage des métadonnées - Nouvelle méthode LoadFrequencyFilter() pour charger un filtre depuis un répertoire - Initialisation des métadonnées lors de la création du filtre - Optimisation des méthodes Union() et Intersect() du KmerSetGroup - Mise à jour du commit hash
This commit is contained in:
@@ -16,10 +16,24 @@ type FrequencyFilter struct {
|
||||
// NewFrequencyFilter crée un nouveau filtre par fréquence
|
||||
// minFreq: nombre minimum d'occurrences requises (v)
|
||||
func NewFrequencyFilter(k, minFreq int) *FrequencyFilter {
|
||||
return &FrequencyFilter{
|
||||
ff := &FrequencyFilter{
|
||||
KmerSetGroup: NewKmerSetGroup(k, minFreq),
|
||||
MinFreq: minFreq,
|
||||
}
|
||||
|
||||
// Initialiser les métadonnées de groupe
|
||||
ff.SetAttribute("type", "FrequencyFilter")
|
||||
ff.SetAttribute("min_freq", minFreq)
|
||||
|
||||
// Initialiser les métadonnées de chaque niveau
|
||||
for i := 0; i < minFreq; i++ {
|
||||
level := ff.Get(i)
|
||||
level.SetAttribute("level", i)
|
||||
level.SetAttribute("min_occurrences", i+1)
|
||||
level.SetId(fmt.Sprintf("level_%d", i))
|
||||
}
|
||||
|
||||
return ff
|
||||
}
|
||||
|
||||
// AddSequence ajoute tous les k-mers d'une séquence au filtre
|
||||
@@ -164,17 +178,67 @@ func (ff *FrequencyFilter) AddSequences(sequences *obiseq.BioSequenceSlice) {
|
||||
// PERSISTANCE
|
||||
// ==================================
|
||||
|
||||
// Save sauvegarde le filtre sur disque
|
||||
func (ff *FrequencyFilter) Save(path string) error {
|
||||
// TODO: implémenter la sérialisation
|
||||
// Pour chaque bitmap: bitmap.WriteTo(writer)
|
||||
return nil
|
||||
// Save sauvegarde le FrequencyFilter dans un répertoire
|
||||
// Utilise le format de sérialisation du KmerSetGroup sous-jacent
|
||||
// Les métadonnées incluent le type "FrequencyFilter" et min_freq
|
||||
//
|
||||
// Format:
|
||||
// - directory/metadata.{toml,yaml,json} - métadonnées du filtre
|
||||
// - directory/set_0.roaring - k-mers vus ≥1 fois
|
||||
// - directory/set_1.roaring - k-mers vus ≥2 fois
|
||||
// - ...
|
||||
// - directory/set_{minFreq-1}.roaring - k-mers vus ≥minFreq fois
|
||||
//
|
||||
// Parameters:
|
||||
// - directory: répertoire de destination
|
||||
// - format: format des métadonnées (FormatTOML, FormatYAML, FormatJSON)
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// err := ff.Save("./my_filter", obikmer.FormatTOML)
|
||||
func (ff *FrequencyFilter) Save(directory string, format MetadataFormat) error {
|
||||
// Déléguer à KmerSetGroup qui gère déjà tout
|
||||
return ff.KmerSetGroup.Save(directory, format)
|
||||
}
|
||||
|
||||
// Load charge le filtre depuis le disque
|
||||
func (ff *FrequencyFilter) Load(path string) error {
|
||||
// TODO: implémenter la désérialisation
|
||||
return nil
|
||||
// LoadFrequencyFilter charge un FrequencyFilter depuis un répertoire
|
||||
// Vérifie que les métadonnées correspondent à un FrequencyFilter
|
||||
//
|
||||
// Parameters:
|
||||
// - directory: répertoire source
|
||||
//
|
||||
// Returns:
|
||||
// - *FrequencyFilter: le filtre chargé
|
||||
// - error: erreur si le chargement échoue ou si ce n'est pas un FrequencyFilter
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// ff, err := obikmer.LoadFrequencyFilter("./my_filter")
|
||||
func LoadFrequencyFilter(directory string) (*FrequencyFilter, error) {
|
||||
// Charger le KmerSetGroup
|
||||
ksg, err := LoadKmerSetGroup(directory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Vérifier que c'est bien un FrequencyFilter
|
||||
if typeAttr, ok := ksg.GetAttribute("type"); !ok || typeAttr != "FrequencyFilter" {
|
||||
return nil, fmt.Errorf("loaded data is not a FrequencyFilter (type=%v)", typeAttr)
|
||||
}
|
||||
|
||||
// Récupérer min_freq
|
||||
minFreqAttr, ok := ksg.GetIntAttribute("min_freq")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("FrequencyFilter missing min_freq attribute")
|
||||
}
|
||||
|
||||
// Créer le FrequencyFilter
|
||||
ff := &FrequencyFilter{
|
||||
KmerSetGroup: ksg,
|
||||
MinFreq: minFreqAttr,
|
||||
}
|
||||
|
||||
return ff, nil
|
||||
}
|
||||
|
||||
// ==================================
|
||||
|
||||
@@ -145,29 +145,69 @@ func (ksg *KmerSetGroup) AddSequences(sequences *obiseq.BioSequenceSlice, index
|
||||
}
|
||||
|
||||
// Union retourne l'union de tous les KmerSet du groupe
|
||||
// Optimisation: part du plus grand ensemble pour minimiser les opérations
|
||||
func (ksg *KmerSetGroup) Union() *KmerSet {
|
||||
if len(ksg.sets) == 0 {
|
||||
return NewKmerSet(ksg.k)
|
||||
}
|
||||
|
||||
result := ksg.sets[0].Copy()
|
||||
for i := 1; i < len(ksg.sets); i++ {
|
||||
result = result.Union(ksg.sets[i])
|
||||
if len(ksg.sets) == 1 {
|
||||
return ksg.sets[0].Copy()
|
||||
}
|
||||
return result
|
||||
|
||||
// Trouver l'index du plus grand ensemble (celui avec le plus de k-mers)
|
||||
maxIdx := 0
|
||||
maxCard := ksg.sets[0].Len()
|
||||
for i := 1; i < len(ksg.sets); i++ {
|
||||
card := ksg.sets[i].Len()
|
||||
if card > maxCard {
|
||||
maxCard = card
|
||||
maxIdx = i
|
||||
}
|
||||
}
|
||||
|
||||
// Copier le plus grand ensemble et faire les unions in-place
|
||||
result := ksg.sets[maxIdx].bitmap.Clone()
|
||||
for i := 0; i < len(ksg.sets); i++ {
|
||||
if i != maxIdx {
|
||||
result.Or(ksg.sets[i].bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
return NewKmerSetFromBitmap(ksg.k, result)
|
||||
}
|
||||
|
||||
// Intersect retourne l'intersection de tous les KmerSet du groupe
|
||||
// Optimisation: part du plus petit ensemble pour minimiser les opérations
|
||||
func (ksg *KmerSetGroup) Intersect() *KmerSet {
|
||||
if len(ksg.sets) == 0 {
|
||||
return NewKmerSet(ksg.k)
|
||||
}
|
||||
|
||||
result := ksg.sets[0].Copy()
|
||||
for i := 1; i < len(ksg.sets); i++ {
|
||||
result = result.Intersect(ksg.sets[i])
|
||||
if len(ksg.sets) == 1 {
|
||||
return ksg.sets[0].Copy()
|
||||
}
|
||||
return result
|
||||
|
||||
// Trouver l'index du plus petit ensemble (celui avec le moins de k-mers)
|
||||
minIdx := 0
|
||||
minCard := ksg.sets[0].Len()
|
||||
for i := 1; i < len(ksg.sets); i++ {
|
||||
card := ksg.sets[i].Len()
|
||||
if card < minCard {
|
||||
minCard = card
|
||||
minIdx = i
|
||||
}
|
||||
}
|
||||
|
||||
// Copier le plus petit ensemble et faire les intersections in-place
|
||||
result := ksg.sets[minIdx].bitmap.Clone()
|
||||
for i := 0; i < len(ksg.sets); i++ {
|
||||
if i != minIdx {
|
||||
result.And(ksg.sets[i].bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
return NewKmerSetFromBitmap(ksg.k, result)
|
||||
}
|
||||
|
||||
// Stats retourne des statistiques pour chaque KmerSet du groupe
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// corresponds to the last commit, and not the one when the file will be
|
||||
// commited
|
||||
|
||||
var _Commit = "16f72e6"
|
||||
var _Commit = "09ac15a"
|
||||
var _Version = "Release 4.4.0"
|
||||
|
||||
// Version returns the version of the obitools package.
|
||||
|
||||
Reference in New Issue
Block a user