diff --git a/pkg/obikmer/kmer_set.go b/pkg/obikmer/kmer_set.go index c0e69d1..0eec9df 100644 --- a/pkg/obikmer/kmer_set.go +++ b/pkg/obikmer/kmer_set.go @@ -10,23 +10,26 @@ import ( // KmerSet encapsule un ensemble de k-mers stockés dans un Roaring Bitmap // Fournit des méthodes utilitaires pour manipuler des ensembles de k-mers type KmerSet struct { - K int // Taille des k-mers - bitmap *roaring64.Bitmap // Bitmap contenant les k-mers + K int // Taille des k-mers + bitmap *roaring64.Bitmap // Bitmap contenant les k-mers + Metadata map[string]interface{} // Métadonnées utilisateur (clé=valeur atomique) } // NewKmerSet crée un nouveau KmerSet vide func NewKmerSet(k int) *KmerSet { return &KmerSet{ - K: k, - bitmap: roaring64.New(), + K: k, + bitmap: roaring64.New(), + Metadata: make(map[string]interface{}), } } // NewKmerSetFromBitmap crée un KmerSet à partir d'un bitmap existant func NewKmerSetFromBitmap(k int, bitmap *roaring64.Bitmap) *KmerSet { return &KmerSet{ - K: k, - bitmap: bitmap, + K: k, + bitmap: bitmap, + Metadata: make(map[string]interface{}), } } @@ -73,9 +76,16 @@ func (ks *KmerSet) Clear() { // Clone crée une copie de l'ensemble func (ks *KmerSet) Clone() *KmerSet { + // Copier les métadonnées + metadata := make(map[string]interface{}, len(ks.Metadata)) + for k, v := range ks.Metadata { + metadata[k] = v + } + return &KmerSet{ - K: ks.K, - bitmap: ks.bitmap.Clone(), + K: ks.K, + bitmap: ks.bitmap.Clone(), + Metadata: metadata, } } diff --git a/pkg/obikmer/kmer_set_group.go b/pkg/obikmer/kmer_set_group.go index 00dbf99..6bbf39e 100644 --- a/pkg/obikmer/kmer_set_group.go +++ b/pkg/obikmer/kmer_set_group.go @@ -9,8 +9,9 @@ import ( // KmerSetGroup représente un vecteur de KmerSet // Utilisé pour gérer plusieurs ensembles de k-mers (par exemple, par niveau de fréquence) type KmerSetGroup struct { - K int // Taille des k-mers - sets []*KmerSet // Vecteur de KmerSet + K int // Taille des k-mers + sets []*KmerSet // Vecteur de KmerSet + Metadata []map[string]interface{} // Métadonnées par KmerSet (même longueur que sets) } // NewKmerSetGroup crée un nouveau groupe de n KmerSets @@ -20,13 +21,16 @@ func NewKmerSetGroup(k int, n int) *KmerSetGroup { } sets := make([]*KmerSet, n) + metadata := make([]map[string]interface{}, n) for i := range sets { sets[i] = NewKmerSet(k) + metadata[i] = make(map[string]interface{}) } return &KmerSetGroup{ - K: k, - sets: sets, + K: k, + sets: sets, + Metadata: metadata, } } @@ -92,12 +96,22 @@ func (ksg *KmerSetGroup) Clear() { // Clone crée une copie complète du groupe func (ksg *KmerSetGroup) Clone() *KmerSetGroup { clonedSets := make([]*KmerSet, len(ksg.sets)) + clonedMetadata := make([]map[string]interface{}, len(ksg.Metadata)) + for i, ks := range ksg.sets { clonedSets[i] = ks.Clone() + + // Copier les métadonnées du groupe + clonedMetadata[i] = make(map[string]interface{}, len(ksg.Metadata[i])) + for k, v := range ksg.Metadata[i] { + clonedMetadata[i][k] = v + } } + return &KmerSetGroup{ - K: ksg.K, - sets: clonedSets, + K: ksg.K, + sets: clonedSets, + Metadata: clonedMetadata, } } diff --git a/pkg/obikmer/kmer_set_persistence.go b/pkg/obikmer/kmer_set_persistence.go index 8339cb6..531d59f 100644 --- a/pkg/obikmer/kmer_set_persistence.go +++ b/pkg/obikmer/kmer_set_persistence.go @@ -36,10 +36,12 @@ func (f MetadataFormat) String() string { // KmerSetMetadata contient les métadonnées d'un KmerSet ou KmerSetGroup type KmerSetMetadata struct { - K int `toml:"k" yaml:"k" json:"k"` // Taille des k-mers - Type string `toml:"type" yaml:"type" json:"type"` // "KmerSet" ou "KmerSetGroup" - Size int `toml:"size" yaml:"size" json:"size"` // 1 pour KmerSet, n pour KmerSetGroup - Files []string `toml:"files" yaml:"files" json:"files"` // Liste des fichiers .roaring + K int `toml:"k" yaml:"k" json:"k"` // Taille des k-mers + Type string `toml:"type" yaml:"type" json:"type"` // "KmerSet" ou "KmerSetGroup" + Size int `toml:"size" yaml:"size" json:"size"` // 1 pour KmerSet, n pour KmerSetGroup + Files []string `toml:"files" yaml:"files" json:"files"` // Liste des fichiers .roaring + UserMetadata map[string]interface{} `toml:"user_metadata,omitempty" yaml:"user_metadata,omitempty" json:"user_metadata,omitempty"` // Métadonnées KmerSet unique + SetsMetadata []map[string]interface{} `toml:"sets_metadata,omitempty" yaml:"sets_metadata,omitempty" json:"sets_metadata,omitempty"` // Métadonnées par set (KmerSetGroup) } // SaveKmerSet sauvegarde un KmerSet dans un répertoire @@ -52,10 +54,11 @@ func (ks *KmerSet) Save(directory string, format MetadataFormat) error { // Métadonnées metadata := KmerSetMetadata{ - K: ks.K, - Type: "KmerSet", - Size: 1, - Files: []string{"set_0.roaring"}, + K: ks.K, + Type: "KmerSet", + Size: 1, + Files: []string{"set_0.roaring"}, + UserMetadata: ks.Metadata, // Sauvegarder les métadonnées utilisateur } // Sauvegarder les métadonnées @@ -105,6 +108,12 @@ func LoadKmerSet(directory string) (*KmerSet, error) { defer file.Close() ks := NewKmerSet(metadata.K) + + // Charger les métadonnées utilisateur + if metadata.UserMetadata != nil { + ks.Metadata = metadata.UserMetadata + } + if _, err := ks.bitmap.ReadFrom(file); err != nil { return nil, fmt.Errorf("failed to read bitmap: %w", err) } @@ -127,10 +136,11 @@ func (ksg *KmerSetGroup) Save(directory string, format MetadataFormat) error { } metadata := KmerSetMetadata{ - K: ksg.K, - Type: "KmerSetGroup", - Size: len(ksg.sets), - Files: files, + K: ksg.K, + Type: "KmerSetGroup", + Size: len(ksg.sets), + Files: files, + SetsMetadata: ksg.Metadata, // Sauvegarder les métadonnées de chaque set } // Sauvegarder les métadonnées @@ -177,6 +187,14 @@ func LoadKmerSetGroup(directory string) (*KmerSetGroup, error) { // Créer le groupe ksg := NewKmerSetGroup(metadata.K, metadata.Size) + // Charger les métadonnées de chaque set + if metadata.SetsMetadata != nil { + if len(metadata.SetsMetadata) != metadata.Size { + return nil, fmt.Errorf("metadata size mismatch: expected %d, got %d", metadata.Size, len(metadata.SetsMetadata)) + } + ksg.Metadata = metadata.SetsMetadata + } + // Charger chaque bitmap for i, filename := range metadata.Files { bitmapPath := filepath.Join(directory, filename) diff --git a/pkg/obioptions/version.go b/pkg/obioptions/version.go index e01e0da..adccd28 100644 --- a/pkg/obioptions/version.go +++ b/pkg/obioptions/version.go @@ -8,7 +8,7 @@ import ( // corresponds to the last commit, and not the one when the file will be // commited -var _Commit = "aa468ec" +var _Commit = "b26b76c" var _Version = "Release 4.4.0" // Version returns the version of the obitools package.