Package: seekr
SEEKRFind communities of nucleotide sequences based onk-mer frequencies.InstallationTo use this library, you have to have >Python3.6 on your computer.Once you have Python, run:$ pip install seekrwhich will make both the command line tool and the python module available.CentOSUsers have been successful in installingseekrfrom source on CentOS:conda create --name seekr_source python=3.8
conda activate seekr_source
git clone https://github.com/CalabreseLab/seekr.git
python3 setup.py install
conda install python-igraph
conda install louvainSeethis issuefor further discussion.UsageYou can either use SEEKR from the command line or as a python module.
The package is broken up into a set of tools, each of which perform a single task.
From the command line, all of the functions will begin withseekr_.
For example, you can useseekr_kmer_countsto generate a normalizedk-mer count matrix ofmrows byncolumns,
wheremis the number of transcripts in a fasta file andnis 4^k-mer.
Thenseekr_pearsoncan be used to calculate how well correlated all pairwise combinations of sequences are.To see all tools and some examples, run:$ seekrQuickstartTo get a .csv file of communities for every transcript in a small .fa file calledexample.fa,
(where RNAs have been normalized to a data set of canonical transcripts fromGENCODE,
we would run:$ seekr_download_gencode lncRNA
$ seekr_canonical_gencode v29_lncRNA.fa v29-01.fa # Name may change with GENCODE updates.
$ seekr_norm_vectors v29-01.fa
$ seekr_kmer_counts example.fa -o 6mers.csv -mv mean.npy -sv std.npy
$ seekr_pearson 6mers.csv 6mers.csv -o example_vs_self.csv
$ seekr_graph example_vs_self.csv 0.13 -g example_vs_self.gml -c communities.csv
$ cat example_vs_self.csvThis quickstart procedure produces a number of other files beside the filecommunities.csv.
See below to learn about the other files produced along the way.Notes:Some advanced usages are not available from the command line and require that you import the module.We'll useexample.faas a small sample set,
if you want to download that file and follow along.GENCODE is a high quality source for human and mouse lncRNA annotation.
Fasta files can be foundhere.In the examples below we'll generically refer togencode.fa.
Any sufficiently large fasta file can be used, as needed.Here are some examples if you just want to get going.Command line examplesseekr_downloadBrowsingGENCODEis nice if you want to explore fasta file options.
But if you know what you want, you can just download it from the command line.
This tool is also helpful on remote clusters.To download all human transcripts of the latest release into a fasta file, run:$ seekr_download_gencode allGENCODE also stores mouse sequences. You can select mouse using the--speciesflag:$ seekr_download_gencode all -s mouseFor consistency across experiments, you may want to stick to a particular release of GENCODE. To get lncRNAs from the M5 release of mouse, use--release:$ seekr_download_gencode lncRNA -s mouse -r M5Finally, if you do not want the script to automatically unzip the file, you can leave the fasta file gzipped with--zip:$ seekr_download_gencode all -zseekr_canonical_gencodeGENCODE fasta files provide multiple transcripts per genomic loci.
To reducek-mer redundancy due to these isoforms,
we can filter for transcripts ending in "01",
as indicated by the sequence headers:$ seekr_canonical_gencode v22_lncRNAs.fa v22-01.faseekr_kmer_countsLet's make a small.csvfile of counts.
We'll set a couple flags:--kmer 2so we only have 16k-mers--outfile out_counts.csv.
This file will contain the log2-transformed z-scores ofk-mer counts per kb.$ seekr_kmer_counts example.fa -o out_counts.csv -k 2
$ cat out_counts.csvYou can also see the output of this commandhere.Three options are available for log transformation, using the--log2flag.
Pass--log2 prefor log transformation of length normalizedk-mer counts, with a +1 pseudo-count,
pass--log2 postfor log transformation of z-scores following count standardization (this is the default),
and pass--log2 nonefor no log transformation.If we want to avoid normalization, we can producek-mer counts per kb by setting the--log2 non,--uncenteredand--unstandardizedflags:$ seekr_kmer_counts example.fa -o out_counts.csv -k 2 --log2 none -uc -usSimilarly, if we want a more compact, efficient numpy file,
we can add the--binaryand--remove_labelflags:$ seekr_kmer_counts example.fa -o out_counts.npy -k 2 --binary --remove_labelNote:This numpy file is binary, so you won't be able to view it directly.What happens if we also remove the--kmer 2option?$ seekr_kmer_counts example.fa -o out_counts.npy
~/seekr/seekr/kmer_counts.py:143: RuntimeWarning: invalid value encountered in true_divide
  self.counts /= self.std

WARNING: You have `np.nan` values in your counts after standardization.
This is likely due to a *k*-mer not appearing in any of your sequences. Try:
1) using a smaller *k*-mer size,
2) beginning with a larger set of sequences,
3) passing precomputed normalization vectors from a larger data set (e.g. GENCODE).The code runs, but we get a warning.
That's because we're normalizing 4096 columns ofk-mers.
Most of thosek-mers never appear in any of our 5 lncRNAs.
This necessarily results in division by 0.
If we use a much larger set ofsequences,
this same line works fine:$ kmer_counts gencode.fa -o gencode_counts.npyBut what should you do if you're only interested in specific sequences?seekr_norm_vectorsAn effective way to find importantk-mers in a small number of RNAs is to
count theirk-mers, but normalize their counts to mean and
standard deviation vectors produced from a larger set of transcripts.
We can produce these vectors once, then use them on multiple smaller sets
of RNAs of interest. To produce the vectors, run:Note:If--log2 postis passed inseekr_kmer_counts, then the--log2 postflag must be passed toseekr_norm_vectors.
This is so that the log-transformedk-mer counts are standardized against referencek-mer counts that are also log transformed.$ seekr_norm_vectors gencode.faIf you runls, you should seemean.npyandstd.npyin your directory.To specify the path of these output files,
use the--mean_vectorand--std_vectorflags:$ seekr_norm_vectors gencode.fa -k 5 -mv mean_5mers.npy -sv std_5mers.npyNow, we can use these vectors to analyze our RNAs of interest:$ kmer_counts example.fa -o out_5mers_gencode_norm.csv -k 5 -mv mean_5mers.npy -sv std_5mers.npyseekr_pearsonTo find Pearson correlations betweenk-mer count profiles, runseekr_pearson.
Running the program and options are similar toseekr_kmers_counts.
Input files forseekr_pearsonwill always be the output files from
one or more runs ofkmer_counts.
The default settings accept two csv files and output a third csv file.$ seekr_pearson out_counts.csv out_counts.csv -o example_vs_self.csv
$ cat example_vs_self.csvThe only other options besides the-oflag control binary versus plain text input and output.
If you have a binary input file (i.e. a .npy file),
and also want a binary output file, you can use the--binary_inputand--binary_outputflags:$ seekr_pearson out_counts.npy out_counts.npy -o example_vs_self.npy -bi -boIf we want to compare counts between two files
(e.g. RNAs between mouse and human),
that is also possible:$ seekr_pearson human_6mers.npy mouse_6mers.npy -o human_vs_mouse.npyseekr_graphWe can treat the results ofseekr_pearsonas anadjacency matrix, and use it to find communities of transcripts with theLouvain algorithmor theLeiden algorithm.The default setting accept a csv file and a threshold value.
This csv file should be the product of seekr_pearson, or some other adjacency matrix.
The threshold is the value below which edges are removed from the graph.
Agmlfile contain the graph and communities will be produced.$ seekr_graph example_vs_self.csv .13 -g example.gmlNumpy files are also valid input:$ seekr_graph example_vs_self.npy .13 -g graph.gmlGML files are plain text, so you can view them if you want.
But they contain all of the information describing the graph.
Often you just want to know what transcripts belong to what community.
To get a csv file mapping transcripts to communities, run:$ seekr_graph example_vs_self.csv .13 -g example.gml -c communities.csvThe value for thresholding the adjacency matrix is very experiment dependent.
Because a reasonable default is difficult to predict, it is a required parameter.
For example, if you are usingk=5, it likely makes sense to increase the threshold (e.g. to .3).seekr_pearson_distrocan be run to suggest a value for the threshold.
Similarly, the community finding algorithm allows you course control of community size with its resolution parameter (gamma).
Testing ranges from .1 to 5 is reasonable, where values from 1-3 have been most useful in our experience.$ seekr_graph example_vs_self.csv .3 -g graph.gml -r 1.5A third tunable parameters is a cap of the number of communities found.
And finally, since community finding is partially random,
you can make your results reproducible by setting a seed value:$ seekr_graph example_vs_self.csv .13 -g graph.gml -n 10 -s 0seekr_gen_rand_rnasIt's often useful to understand what we might expect "at random".
One way to think about "random" with respect tok-mers and RNA sequences,
is to think about what would happen if the nucleotide ork-mer contents was conserved, but shuffled.seekr_gen_rand_rnasprovides a way to conserve but shufflek-mers.To conserve dinucleotide content, for example, run:$ seekr_gen_rand_rnas example.fa example_rand.fa -k 2 -s 0The--kmerflag sets the size of thek-mer,
and the--seedflag makes sure you can reproduce the resulting sequences.
We could now repeat our experiment with the newexample_rand.fafile.Module exampleFor larger or more specific workloads, it may be better to use theseekrmodule.
In this example, we'll calculate similarities between two example fasta files,
(e.g., XIST and a set of RNAs we think could be similar to XIST)
using the normalization vectors from the human GENCODE set.
We'll use allk-mers from 3 to 6, and label transcripts with unique labels.importnumpyasnpimportpandasaspdfromseekr.kmer_countsimportBasicCounterfromseekr.pearsonimportpearsonfromseekr.fasta_readerimportReadergencode='gencode.fa'xist='xist.fa'lncRNAs='other_lncs.fa'# Make sure each lncRNA in other_lncs.fa has a unique nameheaders=Reader(lncRNAs).get_headers()names=[h.strip('>')+f'_{i}'fori,hinenumerate(headers)]forkinrange(3,7):# Make normalization vectorsgencode_counter=BasicCounter(gencode,k=k)gencode_counter.get_counts()mean_path=f'mean_{k}mers.npy'std_path=f'std_{k}mers.npy'np.save(mean_path,gencode_counter.mean)np.save(std_path,gencode_counter.std)# Count *k*-mersxist_counter=BasicCounter(xist,outfile=f'{k}mers_xist.npy',mean=mean_path,std=std_path,k=k)lncs_counter=BasicCounter(lncRNAs,outfile=f'{k}mers_lncs.npy',mean=mean_path,std=std_path,k=k)xist_counter.make_count_file(names=['XIST'])lncs_counter.make_count_file(names=names)# Find similaritiessim=pearson(xist_counter.counts,lncs_counter.counts,outfile=f'xist_vs_lncs_{k}mers.npy')# Save labeled .csv file of similarities.sim_df=pd.DataFrame(sim,['XIST'],names)sim_df.to_csv(f'xist_vs_lncs_{k}mers.csv')Each loop will write six files to disk:mean_{k}mers.npy: Mean vector for GENCODE human lncRNAs.
Once this has been saved, the first portion of the code doesn't need to be run again.std_{k}mers.npy: Standard deviation vector for GENCODE human lncRNAs.{k}mers_xist.npy: Normalizedk-mer profile for Xist.{k}mers_lncs.npy: Normalizedk-mer profile for other lncRNAs of interest.xist_vs_lncs_{k}mers.npy: Pearson's r values for all pairwise comparisons between Xist and the other lncRNAs.xist_vs_lncs_{k}mers.csv: Labeled, plain text version of pairwise comparisons.Additional considerationsThis section is a "not-so-quickstart", providing more complete views on selection of input data and parameter selection.Some general advice for thinking about how to use SEEKR.
One challenge that we continually face in the lab is there are few ground truths in the lncRNA field and thus it is often unclear how to decide on the best parameters for sequence comparisons using SEEKR.
Below are some points that may be useful – these are also discussed in the conclusions ofPMID 31097619Selection of a set of sequences to use for the calculation of standardization vectorsIn our experience, one of the most useful features of SEEKR is that it provides a metric of relative similarity.
Consider two lncRNAs, lncRNA-X, which is from mouse, and lncRNA-Y, which is from human.
One way to compare these two lncRNAs using SEEKR would be to calculate theirk-mer profiles and compare these profiles in relation to all known mouse lncRNAs.
To do this, one would first use all mouse lncRNAs as an input for the "seekr_norm_vectors" script, to determine the mean and standard deviation of counts for allk-mers in all mouse lncRNAs.
Then, users would take those standardization vectors along with the sequences of lncRNA-X and lncRNA-Y and use them in the “kmer_counts” script to calculatek-mer profiles of lncRNA-X and lncRNA-Y in relation to all mouse lncRNAs.
Finally, users would employ the “seekr_pearson” script to determine how similar lncRNA-X and lncRNA-Y were to each other relative to all other mouse lncRNAs.
The point here is that the set of sequences used to calculate standardization vectors is a key variable – perhaps analogous to a reference gene in a quantitative PCR experiment or a loading control in a western blot.
Users should think through what comparison they are interested in performing and choose their set of standardization sequences accordingly.
In the example above, where all mouse lncRNAs were used for standardization, users might discover that “At the level ofk-mers, lncRNA-X is more similar to lncRNA-Y than it is similar to 99% of other mouse lncRNAs”.
But changing the set of sequences for standardization can change the question being asked.
For example, users might be interested in comparing lncRNA-X and lncRNA-Y relative to all known human enhancer RNAs (eRNAs).
Here, using all human eRNAs as the standardization set, users might make an additional insightful discovery, perhaps: “At the level ofk-mers, lncRNA-X is no more similar to lncRNA-Y than it is similar to the average human eRNA”.
Relatedly, when users are comparing two large groups of sequences (let us call these “set A” and “set B”), we again recommend thinking about what set of reference sequences would be best for standardization.
In most cases, users will probably want to use the same set of reference sequences to standardizek-mer counts in set A and in set B.Perhaps set A and set B should again be standardized relative to all mouse lncRNAs; or, both set A and set B be should be standardized relative to the sequences in set B.
But standardizing set A relative to itself, then standardizing set B relative to itself, then using “seekr_pearson” to compare the two sets of sequences might yield a non-sensical comparison.Selection ofk-mer lengthIn our experience, the most robust biological trends have been relatively insensitive to the length ofk-mer used in SEEKR.
Still, when deciding on a length of k to use for comparisons, we recommend using ak-mer length for which 4^k is similar to the length of the average feature or key feature that is being compared.
The reason for this is that as the length of k increases, so does the number of zero values fork-mer counts in a given sequence.
For example, there are 16384 possible 7-mers.
If users were interested in finding lncRNAs that are similar to lncRNA-X, which is 500 nucleotides long, ak-mer length of 7 would not be ideal, because the vector of 7-mer counts that corresponds to lncRNA-X would be dominated by zero values.
In this example, unless users had a specific rationale for searching 7-mers, ak-mer length of 4 (256 possiblek-mers) or 5 (1024 possiblek-mers) would provide the basis for a stronger comparison.Issues and HelpIf you have questions about how you can use seekr in your own research, please send an email tojmcalabr@med.unc.eduFor full documentation, run:$ seekrAny suggestions, questions, or problems can be directed to ourGitHub Issues page.Please also seethe pre-printto a methods paper we wrote last year. This paper was originally scheduled to appear in Methods in Molecular Biology in 2020 but its publication date may be delayed.CitationIf you use this work, please cite:Kirk, J. M., Kim, S. O., Inoue, K., Smola, M. J., Lee, D. M., Schertzer, M. D., … Calabrese, J. M. (2018). Functional classification of long non-coding RNAs by k -mer content. Nature Genetics, 50(10), 1474–1482. https://doi.org/10.1038/s41588-018-0207-8