{"id":22313697,"url":"https://github.com/ctb/zounds","last_synced_at":"2025-06-22T04:38:34.110Z","repository":{"id":823970,"uuid":"538263","full_name":"ctb/zounds","owner":"ctb","description":"Worker bee software for using BLAST and HMMER in Beowulf-style environments","archived":false,"fork":false,"pushed_at":"2010-03-15T15:21:22.000Z","size":4721,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T02:42:53.084Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ctb.png","metadata":{"files":{"readme":"README.html","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-02-27T03:42:22.000Z","updated_at":"2017-12-09T08:53:43.000Z","dependencies_parsed_at":"2022-08-16T11:00:51.924Z","dependency_job_id":null,"html_url":"https://github.com/ctb/zounds","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ctb/zounds","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctb%2Fzounds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctb%2Fzounds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctb%2Fzounds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctb%2Fzounds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ctb","download_url":"https://codeload.github.com/ctb/zounds/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctb%2Fzounds/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261237812,"owners_count":23128843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-03T22:07:57.043Z","updated_at":"2025-06-22T04:38:29.095Z","avatar_url":"https://github.com/ctb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003c!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"\u003e\n\u003chtml xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"\u003e\n\u003chead\u003e\n\u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /\u003e\n\u003cmeta name=\"generator\" content=\"Docutils 0.4: http://docutils.sourceforge.net/\" /\u003e\n\u003ctitle\u003ezounds\u003c/title\u003e\n\u003cstyle type=\"text/css\"\u003e\n\n/*\n:Author: David Goodger\n:Contact: goodger@users.sourceforge.net\n:Date: $Date: 2005-12-18 01:56:14 +0100 (Sun, 18 Dec 2005) $\n:Revision: $Revision: 4224 $\n:Copyright: This stylesheet has been placed in the public domain.\n\nDefault cascading style sheet for the HTML output of Docutils.\n\nSee http://docutils.sf.net/docs/howto/html-stylesheets.html for how to\ncustomize this style sheet.\n*/\n\n/* used to remove borders from tables and images */\n.borderless, table.borderless td, table.borderless th {\n  border: 0 }\n\ntable.borderless td, table.borderless th {\n  /* Override padding for \"table.docutils td\" with \"! important\".\n     The right padding separates the table cells. */\n  padding: 0 0.5em 0 0 ! important }\n\n.first {\n  /* Override more specific margin styles with \"! important\". */\n  margin-top: 0 ! important }\n\n.last, .with-subtitle {\n  margin-bottom: 0 ! important }\n\n.hidden {\n  display: none }\n\na.toc-backref {\n  text-decoration: none ;\n  color: black }\n\nblockquote.epigraph {\n  margin: 2em 5em ; }\n\ndl.docutils dd {\n  margin-bottom: 0.5em }\n\n/* Uncomment (and remove this text!) to get bold-faced definition list terms\ndl.docutils dt {\n  font-weight: bold }\n*/\n\ndiv.abstract {\n  margin: 2em 5em }\n\ndiv.abstract p.topic-title {\n  font-weight: bold ;\n  text-align: center }\n\ndiv.admonition, div.attention, div.caution, div.danger, div.error,\ndiv.hint, div.important, div.note, div.tip, div.warning {\n  margin: 2em ;\n  border: medium outset ;\n  padding: 1em }\n\ndiv.admonition p.admonition-title, div.hint p.admonition-title,\ndiv.important p.admonition-title, div.note p.admonition-title,\ndiv.tip p.admonition-title {\n  font-weight: bold ;\n  font-family: sans-serif }\n\ndiv.attention p.admonition-title, div.caution p.admonition-title,\ndiv.danger p.admonition-title, div.error p.admonition-title,\ndiv.warning p.admonition-title {\n  color: red ;\n  font-weight: bold ;\n  font-family: sans-serif }\n\n/* Uncomment (and remove this text!) to get reduced vertical space in\n   compound paragraphs.\ndiv.compound .compound-first, div.compound .compound-middle {\n  margin-bottom: 0.5em }\n\ndiv.compound .compound-last, div.compound .compound-middle {\n  margin-top: 0.5em }\n*/\n\ndiv.dedication {\n  margin: 2em 5em ;\n  text-align: center ;\n  font-style: italic }\n\ndiv.dedication p.topic-title {\n  font-weight: bold ;\n  font-style: normal }\n\ndiv.figure {\n  margin-left: 2em ;\n  margin-right: 2em }\n\ndiv.footer, div.header {\n  clear: both;\n  font-size: smaller }\n\ndiv.line-block {\n  display: block ;\n  margin-top: 1em ;\n  margin-bottom: 1em }\n\ndiv.line-block div.line-block {\n  margin-top: 0 ;\n  margin-bottom: 0 ;\n  margin-left: 1.5em }\n\ndiv.sidebar {\n  margin-left: 1em ;\n  border: medium outset ;\n  padding: 1em ;\n  background-color: #ffffee ;\n  width: 40% ;\n  float: right ;\n  clear: right }\n\ndiv.sidebar p.rubric {\n  font-family: sans-serif ;\n  font-size: medium }\n\ndiv.system-messages {\n  margin: 5em }\n\ndiv.system-messages h1 {\n  color: red }\n\ndiv.system-message {\n  border: medium outset ;\n  padding: 1em }\n\ndiv.system-message p.system-message-title {\n  color: red ;\n  font-weight: bold }\n\ndiv.topic {\n  margin: 2em }\n\nh1.section-subtitle, h2.section-subtitle, h3.section-subtitle,\nh4.section-subtitle, h5.section-subtitle, h6.section-subtitle {\n  margin-top: 0.4em }\n\nh1.title {\n  text-align: center }\n\nh2.subtitle {\n  text-align: center }\n\nhr.docutils {\n  width: 75% }\n\nimg.align-left {\n  clear: left }\n\nimg.align-right {\n  clear: right }\n\nol.simple, ul.simple {\n  margin-bottom: 1em }\n\nol.arabic {\n  list-style: decimal }\n\nol.loweralpha {\n  list-style: lower-alpha }\n\nol.upperalpha {\n  list-style: upper-alpha }\n\nol.lowerroman {\n  list-style: lower-roman }\n\nol.upperroman {\n  list-style: upper-roman }\n\np.attribution {\n  text-align: right ;\n  margin-left: 50% }\n\np.caption {\n  font-style: italic }\n\np.credits {\n  font-style: italic ;\n  font-size: smaller }\n\np.label {\n  white-space: nowrap }\n\np.rubric {\n  font-weight: bold ;\n  font-size: larger ;\n  color: maroon ;\n  text-align: center }\n\np.sidebar-title {\n  font-family: sans-serif ;\n  font-weight: bold ;\n  font-size: larger }\n\np.sidebar-subtitle {\n  font-family: sans-serif ;\n  font-weight: bold }\n\np.topic-title {\n  font-weight: bold }\n\npre.address {\n  margin-bottom: 0 ;\n  margin-top: 0 ;\n  font-family: serif ;\n  font-size: 100% }\n\npre.literal-block, pre.doctest-block {\n  margin-left: 2em ;\n  margin-right: 2em ;\n  background-color: #eeeeee }\n\nspan.classifier {\n  font-family: sans-serif ;\n  font-style: oblique }\n\nspan.classifier-delimiter {\n  font-family: sans-serif ;\n  font-weight: bold }\n\nspan.interpreted {\n  font-family: sans-serif }\n\nspan.option {\n  white-space: nowrap }\n\nspan.pre {\n  white-space: pre }\n\nspan.problematic {\n  color: red }\n\nspan.section-subtitle {\n  /* font-size relative to parent (h1..h6 element) */\n  font-size: 80% }\n\ntable.citation {\n  border-left: solid 1px gray;\n  margin-left: 1px }\n\ntable.docinfo {\n  margin: 2em 4em }\n\ntable.docutils {\n  margin-top: 0.5em ;\n  margin-bottom: 0.5em }\n\ntable.footnote {\n  border-left: solid 1px black;\n  margin-left: 1px }\n\ntable.docutils td, table.docutils th,\ntable.docinfo td, table.docinfo th {\n  padding-left: 0.5em ;\n  padding-right: 0.5em ;\n  vertical-align: top }\n\ntable.docutils th.field-name, table.docinfo th.docinfo-name {\n  font-weight: bold ;\n  text-align: left ;\n  white-space: nowrap ;\n  padding-left: 0 }\n\nh1 tt.docutils, h2 tt.docutils, h3 tt.docutils,\nh4 tt.docutils, h5 tt.docutils, h6 tt.docutils {\n  font-size: 100% }\n\ntt.docutils {\n  background-color: #eeeeee }\n\nul.auto-toc {\n  list-style-type: none }\n\n\u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\u003cdiv class=\"document\" id=\"zounds\"\u003e\n\u003ch1 class=\"title\"\u003ezounds\u003c/h1\u003e\n\u003cp\u003e'zounds' is a client-server setup for running many parallel commands\n(typically BLAST) on clusters of computers.  It uses XML-RPC to\ncoordinate between the server \u0026amp; clients.\u003c/p\u003e\n\u003cp\u003eThe 'zounds-central' process runs on the server and serves both\nconfiguration information and sequences to clients upon request.\u003c/p\u003e\n\u003cp\u003eThe 'zounds-worker' processes must have access to the command (e.g.\n'blastall' for BLAST, the search database(s) in question, and any code\nyou want to use for post-processing (e.g. the 'blastparser' Python\nmodule).  All of the sequences and configuration information is\nsupplied by the server to the zounds-worker; all of the actual source\ncode needs to be on the client machine where zounds-worker runs.\u003c/p\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"how-does-it-work\" name=\"how-does-it-work\"\u003eHow does it work?\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eWhen you start 'zounds-worker', it contacts the 'zounds-central'\nserver and requests config info and a set of sequences.  It then runs\nwhatever command you've specified (e.g. BLAST) on the sequences\nindividually, with the configured parameters.  The results are then\noptionally passed through some filter (e.g. parsed by blastparser) and\nthen pickled and returned to the server via XML-RPC.  The\n'zounds-central' server saves the returned value as a record in a\n'BsdDbShelf', with the sequence name as the key.\u003c/p\u003e\n\u003cp\u003eBecause XML-RPC works via HTTP, and the clients contact the server,\nthe individual cluster machines need to be able to talk to the server\ndirectly over the network.  However, the server never contacts the\nclients so the cluster can be hidden behind a firewall, proxy, and/or\nNAT.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"installing\" name=\"installing\"\u003eInstalling\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eYou'll need to install \u003ca class=\"reference\" href=\"http://www.python.org\"\u003ePython\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eFor the moment, you need to get zounds via 'git', at\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\ngit\u0026#64;github.com:ctb/zounds.git\n\u003c/pre\u003e\n\u003cp\u003eThis can be done with 'git clone \u003ca class=\"reference\" href=\"http://github.com/ctb/zounds.git\"\u003ehttp://github.com/ctb/zounds.git\u003c/a\u003e'\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"running-zounds-central\" name=\"running-zounds-central\"\u003eRunning 'zounds-central'\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eBriefly,\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython zounds-central \u0026lt;config file\u0026gt; \u0026lt;config section\u0026gt;\n\u003c/pre\u003e\n\u003cp\u003eSee 'config.rc' for examples.\u003c/p\u003e\n\u003cp\u003eFor BLAST, the only trickiness is that the 'blastdb' must be a path\naccessible to the 'zounds-worker' processes, while the 'sequences' and\n'store_db' must be paths on the server.  This is because the sequences\nare sent from the server to the client, and but the actual comparison\nis done on the client.  The same holds true for 'hmmscandb' in hmmer3\nruns: hmmscandb must be accessible on the \u003cem\u003eclient\u003c/em\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"running-zounds-worker\" name=\"running-zounds-worker\"\u003eRunning 'zounds-worker'\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eThe worker process runs on one (or more than one...) node, and\nrequires no configuration other than a server URL:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython zounds-worker [ \u0026lt;server URL\u0026gt; ]\n\u003c/pre\u003e\n\u003cp\u003eFor example,\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython zounds-worker http://localhost:5678/\n\u003c/pre\u003e\n\u003cp\u003econnects to the server process running on 'localhost', configured to\ncommunicate on port 5678.\u003c/p\u003e\n\u003cp\u003e'zounds-worker' takes an optional timeout parameter, given by '-t',\nwhich specifies a time (in minutes) at which the worker process will\nquit.  This is useful for queue systems that penalize processes that\ngo over their configured time limit.  So,\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython zounds-worker -t 1\n\u003c/pre\u003e\n\u003cp\u003ewill exit after 1 minute, overriding any other configuration options.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"an-example\" name=\"an-example\"\u003eAn Example\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eIn one shell, run:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython zounds-central config-dev.rc test\n\u003c/pre\u003e\n\u003cp\u003eIn another shell, run:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython zounds-worker http://localhost:5678/\n\u003c/pre\u003e\n\u003cp\u003eOnce zounds-worker finishes, use CTRL-C to kill the server.\u003c/p\u003e\n\u003cp\u003eNow run:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython dump-raw-output test-output.db\n\u003c/pre\u003e\n\u003cp\u003eYou should get individual BLAST records for each of your query sequences,\nalmost as if you'd simply run 'blastall' locally.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"retrieving-results\" name=\"retrieving-results\"\u003eRetrieving results\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eUse\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\npython -i load_db.py \u0026lt;output filename\u0026gt;\n\u003c/pre\u003e\n\u003cp\u003eYou'll now have a dictionary 'db' containing the keys (query sequences)\nand values.\u003c/p\u003e\n\u003cp\u003eIf you haven't specified a filter, then the values will be tuples:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\n(stdout, stderr)\n\u003c/pre\u003e\n\u003cp\u003efrom the BLAST output.\u003c/p\u003e\n\u003cp\u003e--\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eStupid note:\u003c/strong\u003e that iterating over very large BsdDbShelf databases\nis slow to start, because BsdDbShelf retrieves all of the keys at\nonce.  You can speed things up by using the raw bsddb database to\nretrieve the keys into the shelf:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\n_db = btopen(store_db, 'r')\ndb = BsdDbShelf(_db)\n\nfor key in _db:\n   value = db[key]\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"using-filters\" name=\"using-filters\"\u003eUsing filters\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eFilters can be used both for parsing output and actual filtering of\nresults.\u003c/p\u003e\n\u003cp\u003eA 'filter' is specified in a config file as 'filter='; for example, in\nconfig-dev.rc, section [test_filter],\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\nfilter=filters.parse_blast\n\u003c/pre\u003e\n\u003cp\u003ewmakes each zounds-worker program import the module 'filters' and run\nthe function 'parse_blast' on the stdout and stderr of the subprocess\ncommand; the result is then pickled and passed back to the server.\u003c/p\u003e\n\u003cp\u003eIf the filter returns an empty record (None, or (), \u0026quot;\u0026quot;, or whatever)\nthen that too is pickled and returned.\u003c/p\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch2\u003e\u003ca id=\"parsing-the-blast-results-with-filters-parse-blast\" name=\"parsing-the-blast-results-with-filters-parse-blast\"\u003eParsing the BLAST results with filters.parse_blast\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFor this filter, the blastparser and parse_blast modules must be installed.\u003c/p\u003e\n\u003cblockquote\u003e\nfilter=filters.parse_blast\u003c/blockquote\u003e\n\u003cp\u003eAfter parsing, each record is a blastparser.BlastRecord, and you can\ndo something like this to get some basic results:\u003c/p\u003e\n\u003cpre class=\"literal-block\"\u003e\nrecord = db[seq_name]\nfor hit in record:\n   print hit.subject_name, hit.total_expect\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch2\u003e\u003ca id=\"retrieving-only-a-subset-of-blast-results-with-filters-top-matches-only\" name=\"retrieving-only-a-subset-of-blast-results-with-filters-top-matches-only\"\u003eRetrieving only a subset of BLAST results with filters.top_matches_only\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFilters are useful for situations where you only need a small subset\nof the information: e.g. rather than pickling and encoding a full\nBLAST record, filters can reduce the full blastparser.BlastRecord to\nsomething much smaller.\u003c/p\u003e\n\u003cp\u003eThere's an example filter function in 'filters.py', function\n'top_matches_only'.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"how-well-does-it-scale\" name=\"how-well-does-it-scale\"\u003eHow well does it scale?\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eI've BLASTed 200,000 sequences against the 'nr' database using 128\nsimultaneous workers, without any problems. In theory the disk and\nnetwork I/O should be the most time-consuming aspect of the server,\nand since everything on the server side is threaded, I don't expect\nthere to be server-side performance issues.\u003c/p\u003e\n\u003cp\u003eOn the client side there are likely to be a few performance problems:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003col class=\"arabic simple\"\u003e\n\u003cli\u003eBLAST is run on each sequence individually, for simplicity's sake.\nThis means the BLAST database is reloaded for every BLAST.  This\ncould be optimized at the expense of a bit more code complexity\nin 'zounds-worker'.\u003c/li\u003e\n\u003cli\u003eThe worker submits the BLAST data to the server directly, without\nstarting a thread.  This means that if the server or network\nis really busy, the worker may be network-bound.  (This should be\nparticularly easy to fix.)\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eNone of these problems prevent zounds from working and so I just\nignore 'em.  You can fix them if you like.  Personally I'd prefer to\nkeep the worker code as simple as possible, but it should be fairly\neasy to hack performance improvements in if you need or want them.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"author-info\" name=\"author-info\"\u003eAuthor Info\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003ezounds was hacked together by C. Titus Brown, \u0026lt;\u003ca class=\"reference\" href=\"mailto:titus\u0026#64;idyll.org\"\u003etitus\u0026#64;idyll.org\u003c/a\u003e\u0026gt;.  It is\nfreely available under the BSD license.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"acknowledgements\" name=\"acknowledgements\"\u003eAcknowledgements\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003eTracy Teal and Qingpeng Zhang alpha- and beta-tested zounds.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"section\"\u003e\n\u003ch1\u003e\u003ca id=\"questions\" name=\"questions\"\u003eQuestions?\u003c/a\u003e\u003c/h1\u003e\n\u003cp\u003ePlease contact the \u003ca class=\"reference\" href=\"http://lists.idyll.org/listinfo/biology-in-python\"\u003ebiology-in-python\u003c/a\u003e mailing list with\nany questions or comments about zounds.\u003c/p\u003e\n\u003cp\u003e--\u003c/p\u003e\n\u003cp\u003eTODO:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul class=\"simple\"\u003e\n\u003cli\u003euse sqlite shelve instead, for storing results\u003c/li\u003e\n\u003cli\u003efix/work with screed v2\u003c/li\u003e\n\u003cli\u003eautomatically set number of comparisons/seqs in db for BLAST and HMMER\u003c/li\u003e\n\u003cli\u003eundone sequences flush/reset at end\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eBigger plans?\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul class=\"simple\"\u003e\n\u003cli\u003estatus Web site for zounds-central\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e--\u003c/p\u003e\n\u003cp\u003eCTB: Woods Hole MBL, 7/2008; MSU 3/2010.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fctb%2Fzounds","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fctb%2Fzounds","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fctb%2Fzounds/lists"}