{ Les snippets de bioinfo-fr.net }


Average timeit [Python]

26.02.2019     Yo_O      timer python chronophage temps benchmark 

  Une fonction timeit permettant de placer @timeit en decorateur d'une methode à chronométrer.
Petit bonus : joue n fois la méthode décorée et rend le temps moyen.

source originale : https://github.com/realpython/materials/blob/master/pandas-fast-flexible-intuitive/tutorial/timer.py
import functools
import gc
import itertools
import sys
from timeit import default_timer as _timer


def timeit(_func=None, *, repeat=3, number=1000, file=sys.stdout):
    """Decorator: prints time from best of `repeat` trials.
    Mimics `timeit.repeat()`, but avg. time is printed.
    Returns function result and prints time.
    You can decorate with or without parentheses, as in
    Python's @dataclass class decorator.
    kwargs are passed to `print()`.
    >>> @timeit
    ... def f():
    ...     return "-".join(str(n) for n in range(100))
    ...
    >>> @timeit(number=100000)
    ... def g():
    ...     return "-".join(str(n) for n in range(10))
    ...
    """

    _repeat = functools.partial(itertools.repeat, None)

    def wrap(func):
        @functools.wraps(func)
        def _timeit(*args, **kwargs):
            # Temporarily turn off garbage collection during the timing.
            # Makes independent timings more comparable.
            # If it was originally enabled, switch it back on afterwards.
            gcold = gc.isenabled()
            gc.disable()

            try:
                # Outer loop - the number of repeats.
                trials = []
                for _ in _repeat(repeat):
                    # Inner loop - the number of calls within each repeat.
                    total = 0
                    for _ in _repeat(number):
                        start = _timer()
                        result = func(*args, **kwargs)
                        end = _timer()
                        total += end - start
                    trials.append(total)

                # We want the *average time* from the *best* trial.
                # For more on this methodology, see the docs for
                # Python's `timeit` module.
                #
                # "In a typical case, the lowest value gives a lower bound
                # for how fast your machine can run the given code snippet;
                # higher values in the result vector are typically not
                # caused by variability in Python’s speed, but by other
                # processes interfering with your timing accuracy."
                best = min(trials) / number
                print(
                    "Best of {} trials with {} function"
                    " calls per trial:".format(repeat, number)
                )
                print(
                    "Function `{}` ran in average"
                    " of {:0.3f} seconds.".format(func.__name__, best),
                    end="\n\n",
                    file=file,
                )
            finally:
                if gcold:
                    gc.enable()
            # Result is returned *only once*
            return result

        return _timeit

    # Syntax trick from Python @dataclass
    if _func is None:
        return wrap
    else:
        return wrap(_func)
0/5 - [0 vote]




Simple Fast Kmer counter (with small k) [C++]

28.01.2019     Natir      cpp kmer counter 

  A simple and fast kmer counter.

limitation:
- k must always be odd
- k must be choose at compile time
- the memory usage is 2 ^ (k*2-1) bytes
- in this version the maximum count of a kmer is 255 (see comments)
- in this version the maximum value of k is 31 (see comments)
- forward and reverse kmers are counted at the same time


The main function provides a simple example.
#include <bitset>

template <size_t K>
using kmer_t = typename std::conditional<
  K <= 4 && K % 2 == 1,
  std::uint_least8_t,
  typename std::conditional<
    K <= 8 && K % 2 == 1,
    std::uint16_t,
    typename std::conditional<
      K <= 16 && K % 2 == 1,
      std::uint32_t,
      typename std::conditional<
        K <= 32 && K % 2 == 1,
        std::uint64_t,
        std::false_type
      >::type
    >::type
  >::type
>::type;

template <std::uint8_t K>
constexpr std::uint64_t comp_mask() {
  if(K <= 4 && K % 2 == 1) {
    return 0b10101010;
  } else if(K <= 8 && K % 2 == 1) {
    return 0b1010101010101010;
  } else if(K <= 16 && K % 2 == 1) {
    return 0b10101010101010101010101010101010;
  } else if(K <= 32 && K % 2 == 1) {
    return 0b1010101010101010101010101010101010101010101010101010101010101010;
  } else {
    return 0;
  }
}

template <std::uint8_t K>
constexpr std::uint64_t max_k() {
  if(K <= 4) {
    return 4;
  } else if(K <= 8) {
    return 8;
  } else if(K <= 16) {
    return 16;
  } else if(K <= 32) {
    return 32;
  } else {
    return 0;
  }
}	     

template<std::uint8_t K>
kmer_t<K> seq2bit(std::string seq) {
  kmer_t<K> kmer = 0;
  
  for(auto n: seq) {
    kmer <<= 2;
    kmer |= ((n >> 1) & 0b11);
  }
  
  return kmer;
}

template<std::uint8_t K>
kmer_t<K> reverse_2(kmer_t<K> kmer) {
  kmer_t<K> reversed = 0;

  for(kmer_t<K> i = 0; i < K-1; ++i) {
    reversed = (reversed ^ (kmer & 0b11)) << 2;
    kmer >>= 2;
  }
  
  return reversed ^ (kmer & 0b11);
}

template<std::uint8_t K>
uint8_t parity(kmer_t<K> kmer) {
  return std::bitset<K*2>(kmer).count() % 2; 
}
 
template<std::uint8_t K>
kmer_t<K> get_cannonical(kmer_t<K> kmer) {
  uint8_t cleaning_move = (max_k<K>() - K) * 2;

  if(parity<K>(kmer) == 0) {
    return kmer;
  } else {
    
    kmer_t<K> hash = (reverse_2<K>(kmer) ^ comp_mask<K>());
    hash <<= cleaning_move;
    hash >>= cleaning_move;
        
    return hash;
  }
}

template<std::uint8_t K>
kmer_t<K> hash_kmer(kmer_t<K> kmer) {
  return get_cannonical<K>(kmer) >> 1;
}

#include <iostream>
#include <vector>

int main(int argc, char* argv[]) {

  constexpr std::uint8_t k = 3; // must be odd and minus than 32 change test at line 119

  std::string seq = "AAACCCTTTGGG";

  // To increase maximal count change uint8_t, to unint16_t, uint32_t or uint64_t
  std::vector<std::uint8_t> kmer2count(1 << (k * 2 -1), 0); // 1 << n <-> 2^n

  for(size_t i = 0; i != seq.length() - k + 1; i++) {
    std::string sub_seq = seq.substr(i, k);
    
    uint32_t hash = hash_kmer<k>(seq2bit<k>(sub_seq));

    if(kmer2count[hash] != 255) {
      kmer2count[hash]++;
    }
  }
  
  for(size_t i = 0; i != kmer2count.size(); i++) {
    std::cout<<int(kmer2count[i])<<" ";
  }
  std::cout<<std::endl;
  
  return 0;
}
5/5 - [1 vote]




Conversion d'encodage pour fichier tabulé [Bash]

12.10.2018     Yo_O      utf8 encodage csv excel tableau données cli 

  A l'aide de iconv (https://en.wikipedia.org/wiki/Iconv), vous pouvez maintenant arranger n'importe quel fichier tabulé "mal encodé" (comprendre "pas encodé en UTF-8") venant de vos biologistes préférés en une petite ligne.
iconv -f iso-8859-1 -t utf-8 input_file_in_ISO8859-1.csv > output_file_in_UTF8.csv
5/5 - [1 vote]




From FastQ to Fasta format [Bash]

04.10.2018     mathildefog      bash fastq fasta 

  Transforme un ficher fastq en fichier fasta.
cat myFile.fastq | paste - - - - | sed 's/^@/>/g'| cut -f1-2 | tr '\t' '\n' > myFile.fasta
5/5 - [2 votes]




louvain [Python]

24.09.2018     Mathurin      louvain 

  version de louvain trouvé en python
import numpy as np
import os


def genlouvain(B, seed=None):
    '''
    The optimal community structure is a subdivision of the network into
    nonoverlapping groups of nodes which maximizes the number of within-group
    edges and minimizes the number of between-group edges.
    This function is a fast an accurate multi-iterative generalization of the
    louvain community detection algorithm. This function subsumes and improves
    upon modularity_[louvain,finetune]_[und,dir]() and additionally allows to
    optimize other objective functions (includes built-in Potts Model i
    Hamiltonian, allows for custom objective-function matrices).
    Parameters
    ----------
    B : str | NxN np.arraylike
        string describing objective function type, or provides a custom
        objective-function matrix. builtin values 'modularity' uses Q-metric
        as objective function, or 'potts' uses Potts model Hamiltonian.
        Default value 'modularity'.
    seed : int | None
        random seed. default value=None. if None, seeds from /dev/urandom.
    Returns
    -------
    ci : Nx1 np.array
        final community structure
    q : float
        optimized q-statistic (modularity only)
    '''
    np.random.seed(seed)
    st0 = np.random.get_state()

    n = len(B)
    ci = np.arange(n) + 1
    Mb = ci.copy()

    B = np.squeeze(np.asarray(B))
    B = (B + B.T)/2.0
    Hnm = np.zeros((n, n))
    for m in range(1, n + 1):
        Hnm[:, m - 1] = np.sum(B[:, ci == m], axis=1)  # node to module degree
    H = np.sum(Hnm, axis=1)  # node degree
    Hm = np.sum(Hnm, axis=0)  # module degree

    q0 = -np.inf
    # compute modularity
    q = np.sum(B[np.tile(ci, (n, 1)) == np.tile(ci, (n, 1)).T])

    first_iteration = True

    while q - q0 > 1e-10:
        it = 0
        flag = True
        while flag:
            it += 1
            if it > 1000:
                raise ValueError('Modularity infinite loop style G. '
                                    'Please contact the developer.')
            flag = False
            for u in np.random.permutation(n):
                ma = Mb[u] - 1
                dQ = Hnm[u, :] - Hnm[u, ma] + B[u, u]  # algorithm condition
                dQ[ma] = 0

                max_dq = np.max(dQ)
                if max_dq > 1e-10:
                    flag = True
                    mb = np.argmax(dQ)
                    Hnm[:, mb] += B[:, u]
                    Hnm[:, ma] -= B[:, u]  # change node-to-module strengths

                    Hm[mb] += H[u]
                    Hm[ma] -= H[u]  # change module strengths

                    Mb[u] = mb + 1

        _, Mb = np.unique(Mb, return_inverse=True)
        Mb += 1

        M0 = ci.copy()
        if first_iteration:
            ci = Mb.copy()
            first_iteration = False
        else:
            for u in range(1, n + 1):
                ci[M0 == u] = Mb[u - 1]  # assign new modules

        n = np.max(Mb)
        b1 = np.zeros((n, n))
        for i in range(1, n + 1):
            for j in range(i, n + 1):
                # pool weights of nodes in same module
                bm = np.sum(B[np.ix_(Mb == i, Mb == j)])
                b1[i - 1, j - 1] = bm
                b1[j - 1, i - 1] = bm
        B = b1.copy()

        Mb = np.arange(1, n + 1)
        Hnm = B.copy()
        H = np.sum(B, axis=0)
        Hm = H.copy()

        q0 = q
        q = np.trace(B) # compute modularity
        dir = 'output'
        if not os.path.isdir(dir): os.makedirs(dir)
        
        output = open (os.path.join(dir, 'gen_louvain_seed.txt'),'a+')
        print >> output, "%i" % (st0[1][0])


    return ci, q
0/5 - [0 vote]




Lister les screens ouverts sur des serveurs distants [Bash]

28.08.2018     Kumquatum      tool bashrc screen 

  Affiche le nom de vos screens ouvert sur une liste de serveurs donnés
À ajouter dans le .bashrc pour une utilisation rapide
function screenAllServ ()
{
echo -e "#######################\n### Current screens ###\n#######################"
for servName in Serv1 Serv2 Serv3
do
ssh username@$servName.adresse.de.mon.serveur.com "echo -e \"----\n<><><> \"\$(hostname)\"<><><>\"; ls /var/run/screen/S-username/ | cat"
done
} 
0/5 - [0 vote]




Cartographie R [R]

27.08.2018     Remy_Moine      cartographie points polygones vecteurs SIG 

  Un essai de synthèse des éléments rassemblés pour obtenir une carte de différentes données vecteur sous R.

Il est basé en partie sur les éléments donnés par la R-Graph Gallery (https://www.r-graph-gallery.com/). De plus amples explications sont disponibles sur ce site.

Les données en entrée doivent suivre une projection Mercator (EPSG 3857).

packages additionels: "ggplot2,ggmap, broom, sp, rgdal, maptools, plyr, rgeos"

R version 3.4.4
OS: Linux Xubuntu 16.04
library(ggmap)
library(ggplot2)
library(broom)
library(sp)
library(rgdal)
library(maptools)
library(plyr)
library(rgeos)

# stockage des projections usuelles
l93a<-"+init=epsg:27572"
l93<-"+init=epsg:2154"
wgs84<-"+init=epsg:4326"
merca<-"+init=epsg:3857"

# Chargement d'une couche de polygones représentant des secteurs de prospection
secteurs<-readOGR( dsn= getwd() , layer="secteurs") 
proj4string(secteurs)<-CRS(l93)
# Extraction des vertex du polygone pour être représenté sous ggplot.
secteurs@data$id = rownames(secteurs@data)
secteurs.points = fortify(secteurs,region="id")
secteurs.df = join(secteurs.points, secteurs@data,by="id")

# Création d'un point géolocalisé d'inventaire
# !ATTENTION ! Tout doit être en epsg 3857
centro<-as.data.frame(cbind(lon=c(44.95),lat=c(6.10)))# tableau contenant les points EN MERCATOR (EPSG=3857 !!!)

# Récupération d'un fond cartographique googlemap satellite
# Le fond cartographique couvre la zone spécifiée entre guillemet (donc ici la France). La recherche s'effectue comme dans Googl...aps.
map <- ggmap(get_googlemap("France", zoom = 10, maptype = "satellite"))# zoom à 0-> terre entière, zoom à 20-> champs en détail, 

# Assemblage final
carte<-map +
  geom_point(data=centro,aes(x=lat,y=lon,colour=rownames(centro),shape=rownames(centro)),size=3)+
  xlab("Longitude")+ ylab("Latitude")+
  scale_color_manual(values=c("blue"))+
  theme(legend.position='none')
0/5 - [0 vote]




Test de Mac-Nemar par regroupement pour analyse diachronique par mailles [R]

27.08.2018     Remy_Moine      MacNemar boucle treemap 

  Permet de calculer pour différents regroupements d'individus statistiques (ici des mailles de présence-absence) les valeurs du test de Mac Nemar.
Demande en entrée un tableau avec le nom du regroupement, le nombre d'individus statistiques où le caractère observé est absent, apparait, disparait et se maintient entre t et t+1.

Packages additionels: "treemap", "RColorBrewer"

R version 3.4.4
OS: Linux Xubuntu 16.04
setwd()

library(treemap)
library(RColorBrewer)

tabl #contient vos données  en entrée classe data.frame

## Préparation des vecteurs nécessaires au fonctionnement de du script:

Somme<-rep(0,nrow(tabl)) # stock le nombre total d'individus statistiques
stat_mcnemar<-rep(0,nrow(tabl)) # stock la VTZ² pour chaque regroupement
pvalue_mcnemar<-rep(0,nrow(tabl)) # stock la p.value pour chaque regroupement
Applicable<-rep(NA,nrow(tabl)) # stock la condition d'appliation du test
Linkimg<-rep(0,nrow(tabl)) # stock le lien vers la sortie graphique

## Boucle de calcul des paramètres du test et des sorties graphiques par regroupement

for (i in c(1:nrow(tabl))){

  # Vérifie que le test de Mac-Nemar est applicable
  Somme[i]<-sum(tabl[i,c(1:4)])
  Applicable[i]<- tabl[i,3]+tabl[i,2]

  # Produit une matrice pour le test de Mac-Nemar
  mat<-matrix(c(tabl[i,4],tabl[i,2],tabl[i,3],tabl[i,1]),ncol=2)

  # Stockage des résultats du test avec signalement des regroupements où il n'est pas applicable
  if (Applicable[i] < 20) stat_mcnemar[i]<- "test non applicable"
  else stat_mcnemar[i]<-mcnemar.test(mat)$statistic

  if (Applicable[i] < 20) pvalue_mcnemar[i]<- "test non applicable"
  else pvalue_mcnemar[i]<-mcnemar.test(mat)$p.value

  # Export du graphique résumant la répartition des mailles sur le site et stockage du chemin d'accès dans le tableau
  sign<-NULL
  if (mcnemar.test(mat)$p.value == "NaN") sign<- c("NA") else
    if (mcnemar.test(mat)$p.value < 0.01) sign<-c("***") else
      if (mcnemar.test(mat)$p.value < 0.05) sign<-c("**") else
        if (mcnemar.test(mat)$p.value < 0.1) sign<-c("*") else sign<-c("-")
  # permet de synthétiser la p.value sous forme d'un code à étoiles

  value=c(export[i,4],export[i,2],export[i,3],export[i,1])
  group=c(paste("Maintien: ",export[i,4]," mailles",sep=''),
          paste("Apparition: ",export[i,2]," mailles",sep=''),
          paste("Disparition: ",export[i,3]," mailles",sep=''),
          paste("Absence: ",export[i,1]," mailles",sep=''))
  Tab=data.frame(group,value)
  Titre<-NULL
  if (Applicable[i] == 0) Titre<- c("Non Applicable") else
    Titre<- paste(round(mcnemar.test(mat)$statistic,3)," (",sign,")",sep='')
  photo<-paste(getwd(),rownames(export[i,]),".jpg",sep='')

colors <- c("#FFFF00","#FF0000","#0000FF","#FF00FF")
group=c("Maintien","Apparition","Disparition","Absence")

  jpeg(filename=photo,res=600,width=6,height=6,units="cm")
  treemap(Tab,
          index="group",
          vSize="value",
          type="index",
          palette=colors,
          fontsize.labels = 5,
          force.print.labels = T,
          fontface.labels = 4,
          title= Titre,
          fontsize.title = 10,
          border.lwds= 0.5,
          fontcolor.labels="black")
  dev.off()

  Linkimg[i]<-photo
}

export1<-cbind(tabl,Somme,stat_mcnemar,pvalue_mcnemar,Linkimg)
write.csv(export1,paste(getwd(),"/res-mcnemar.csv",sep=''))
0/5 - [0 vote]




Compter le nombre de lignes en fonction du contenu d'une colonne [Bash]

07.08.2018     anicolas      comptage occurence tsv 

  
Exemple
Vous voulez compter le nombre d'occurence de chaque type, à partir du fichier tabulé suivant :
id value type
1 5698 typeA
2 569 typeB
3 3658 typeC
4 532 typeB
5 123 typeA

Vous obtenez :
typeA 2
typeB 2
typeC 1

Usage :
Le fichier tabulé doit avoir une ligne avec les noms de colonnes
Pour le lancer
./count_file.sh fichier_tabulé.txt numero_de_colonne_à_compter
#!/bin/bash
#s'il manque un argument, le script n'est pas lance
if [ $# -ne 2 ]; then echo 'Syntaxe: count_file.sh DE_file_with_annot.txt column_number_to_count'; exit 66; fi

#ecrit un fichier temporaire sans les noms de colonnes
tail -n +2 $1 >> $1.temp
#recupere le prefixe du nom de fichier pour ecrire le nom du fichier de sortie
prefix=$(basename $1 .txt)
output=$prefix"_column_num_"$2"_count.txt"
#creation du fichier de sortie et du fichier temporaire de sortie
temp="temp.txt"
touch $output
touch $temp

#lecture du fichier tabule ligne par ligne
while read line
do
#recupere la valeur de la colonne a compter
current_value=`echo "$line" | awk -F $"\t" '{print $'$2'}'`
#cherche dans le fichier de sortie si cette valeur existe. Si elle existe, augmente d'un le compteur pour cette valeur. Si elle n'existe pas, elle est cree et son compteur est initie a 1. Ecrit l'ancien fichier de sortie + les nouvelles infos dans un fichier temporaire
awk -F $"\t" -v value="$current_value" 'BEGIN{ OFS = FS ; found = "no"} {if( $1 == value ) {print $1, $2+1 ; found = "ok"} else {print $0}} END {if (found == "no") {print value, 1} }' $output >> $temp
#remplace le fichier de sortie par le fichier temporaire
mv $temp $output
done<$1.temp

#efface le fichier tabule sans les noms de colonnes
rm $1.temp
1/5 - [1 vote]




Visualisations d'ACP interactives et colorées ! [R]

31.07.2018     gdevailly      r PCA ACP plotly interactive plots 

  Visualiser des ACP (PCA in english) est une tâche assez commune, mais qui peut-être laborieuse si vous êtes pointilleux comme moi ou ZaZo0o (cf https://bioinfo-fr.net/representer-facilement-une-acp-avec-r-et-ggplot2).

Je vous présente ici une méthode pour faire des ACP interactives (avec zoom, masquage des groupes, noms des points en mouseover, etc.).

Il vous faut installer dplyr, cowplot et plotly depuis CRAN.
library(cowplot)
library(plotly)
library(dplyr)

plotPCA <- function(
    my_pca,
    colorby = NULL,
    xaxs = "PC1", yaxs = "PC2",
    title = NULL,
    palette = function(x) rainbow(x, s = 0.6),
    continuous_color = FALSE,
    ...
) {
    
    # obtaining % of variance explained by each axis
    varxaxs <- (summary(my_pca)$importance["Proportion of Variance", xaxs] * 100) %>% round(digits = 1)
    varyaxs <- (summary(my_pca)$importance["Proportion of Variance", yaxs] * 100) %>% round(digits = 1)
    
    myplot <- tibble(
        myxaxs = my_pca$x[, xaxs],
        myyaxs = my_pca$x[, yaxs],
        texts = rownames(my_pca$x),
        colors = if (is.null(colorby)) {NA} else {colorby}
    ) %>%
        ggplot(aes(x = myxaxs, y = myyaxs, color = colors, text = texts)) +
        geom_point() +
        labs(x = paste0(xaxs, " (", varxaxs, "%)"), y = paste0(yaxs, " (", varyaxs, "%)"), title = title, color = NULL) +
        background_grid()
    
    if (continuous_color) {
        myplot <- myplot + scale_color_gradientn(colors = palette(64))
    } else {
        myplot <- myplot + scale_color_manual(values = palette(n_distinct(colorby)))
    }
    
    ggplotly(myplot, tooltip = "text", ...)
    
}

# generating data for the example
metadata <- tibble(
    group = rep(c("group1", "group2", "group3"), each = 50),
    names = paste("sample", 1:150),
    latent_variable = c(
        rnorm(100) + 4,
        rnorm(50)
    )
)
my_data <- matrix(rnorm(150 * 15), nrow = 150)
my_data[1:100, 1:10] <- my_data[1:50, 1:10] + 3 # PC1 axis differences
my_data[1:50, 11:15] <- my_data[1:50, 11:15] + 2 # PC2 differences 
rownames(my_data) <- metadata$names

# basic example (click on legend to hide/display specific groups):
plotPCA(prcomp(my_data), colorby = metadata$group)

# changing axis and title
plotPCA(prcomp(my_data), colorby = metadata$group, xaxs = "PC2", yaxs = "PC3", title = "PC1 not shown")

# changing color palette:
plotPCA(prcomp(my_data), colorby = metadata$group, palette = viridis::viridis)

# continuous colors:
plotPCA(prcomp(my_data), colorby = metadata$latent_variable, palette = viridis::viridis, continuous_color = TRUE)

# saving as html:
p <- plotPCA(prcomp(my_data), colorby = metadata$group)
htmlwidgets::saveWidget(p, "my_great_pca.html", selfcontained = TRUE)


0/5 - [0 vote]





Ancients snippets >>>
Powered by canSnippet CE - by ademcan