{"action":"created","comment":{"url":"https://api.github.com/repos/ged-lab/khmer/pulls/comments/24514536","id":24514536,"diff_hunk":"@@ -0,0 +1,295 @@\n+#! /usr/bin/env python2\n+#\n+# This file is part of khmer, http://github.com/ged-lab/khmer/, and is\n+# Copyright (C) Michigan State University, 2009-2014. It is licensed under\n+# the three-clause BSD license; see doc/LICENSE.txt.\n+# Contact: khmer-project@idyll.org\n+#\n+\"\"\"\n+Trim sequences at k-mers of the given abundance, using a streaming algorithm.\n+Output sequences will be placed in 'infile.abundtrim'.\n+\n+% python scripts/trim-low-abund.py [ <data1> [ <data2> [ ... ] ] ]\n+\n+Use -h for parameter help.\n+\n+TODO: load/save counting table.\n+TODO: reference appropriate preprint.\n+\"\"\"\n+import sys\n+import screed\n+import os\n+import khmer\n+import tempfile\n+import shutil\n+import textwrap\n+\n+from screed.screedRecord import _screed_record_dict\n+from khmer.khmer_args import build_counting_args\n+from khmer.utils import (write_record, write_record_pair, broken_paired_reader)\n+\n+\n+DEFAULT_NORMALIZE_LIMIT = 20\n+DEFAULT_CUTOFF = 2\n+\n+# see Zhang et al., http://arxiv.org/abs/1309.2975\n+MAX_FALSE_POSITIVE_RATE = 0.8\n+\n+\n+def trim_record(read, trim_at):\n+    new_read = _screed_record_dict()\n+    new_read.name = read.name\n+    new_read.sequence = read.sequence[:trim_at]\n+    if hasattr(read, 'accuracy'):\n+        new_read.accuracy = read.accuracy[:trim_at]\n+\n+    return new_read\n+\n+\n+def get_parser():\n+    epilog = \"\"\"\n+    The output is one file for each input file, <input file>.abundtrim, placed\n+    in the current directory.  This output contains the input sequences\n+    trimmed at low-abundance k-mers.\n+\n+    The ``-V/--variable-coverage`` parameter will, if specified,\n+    prevent elimination of low-abundance reads by only trimming\n+    low-abundance k-mers from high-abundance reads; use this for\n+    non-genomic data sets that may have variable coverage.\n+\n+    Note that the output reads will not necessarily be in the same order\n+    as the reads in the input files; if this is an important consideration,\n+    use ``load-into-counting.py`` and ``filter-abund.py``.  However, read\n+    pairs will be kept together, in \"broken-paired\" format; you can use\n+    ``extract-paired-reads.py`` to extract read pairs and orphans.\n+\n+    Example::\n+\n+        trim-low-abund.py -x 5e7 -k 20 -C 2 data/100k-filtered.fa\n+    \"\"\"\n+\n+    parser = build_counting_args(\n+        descr='Trim low-abundance k-mers using a streaming algorithm.',\n+        epilog=textwrap.dedent(epilog))\n+\n+    parser.add_argument('--cutoff', '-C', type=int,\n+                        help='remove k-mers below this abundance',\n+                        default=DEFAULT_CUTOFF)\n+\n+    parser.add_argument('--normalize-to', '-Z', type=int,\n+                        help='base cutoff on this median k-mer abundance',\n+                        default=DEFAULT_NORMALIZE_LIMIT)\n+\n+    parser.add_argument('--variable-coverage', '-V', action='store_true',\n+                        default=False,\n+                        help='Only trim low-abundance k-mers from sequences '\n+                        'that have high coverage.')\n+\n+    parser.add_argument('--tempdir', '-T', type=str, default='./')\n+\n+    parser.add_argument('input_filenames', nargs='+')\n+\n+    return parser\n+\n+\n+def main():\n+    parser = get_parser()\n+    args = parser.parse_args()\n+\n+    ###\n+\n+    if len(set(args.input_filenames)) != len(args.input_filenames):\n+        print >>sys.stderr, \\\n+            \"Error: Cannot input the same filename multiple times.\"\n+        sys.exit(1)\n+\n+    ###\n+\n+    K = args.ksize\n+\n+    CUTOFF = args.cutoff\n+    NORMALIZE_LIMIT = args.normalize_to\n+\n+    print >>sys.stderr, 'making counting table'\n+    ct = khmer.new_counting_hash(K, args.min_tablesize, args.n_tables)\n+\n+    tempdir = tempfile.mkdtemp('khmer', 'tmp', args.tempdir)\n+    print >>sys.stderr, 'created temporary directory %s; ' \\\n+                        'use -T to change location' % tempdir\n+\n+    # ### FIRST PASS ###\n+\n+    save_pass2_total = 0\n+\n+    n_bp = 0\n+    n_reads = 0\n+    written_bp = 0\n+    written_reads = 0\n+    trimmed_reads = 0\n+\n+    pass2list = []\n+    for filename in args.input_filenames:\n+        pass2filename = os.path.basename(filename) + '.pass2'\n+        pass2filename = os.path.join(tempdir, pass2filename)\n+        trimfilename = os.path.basename(filename) + '.abundtrim'\n+\n+        pass2list.append((filename, pass2filename, trimfilename))\n+\n+        screed_iter = screed.open(filename)\n+        pass2fp = open(pass2filename, 'w')\n+        trimfp = open(trimfilename, 'w')\n+\n+        save_pass2 = 0\n+        for n, is_pair, read1, read2 in broken_paired_reader(screed_iter):\n+            if n % 10000 == 0:\n+                print >>sys.stderr, '...', n, filename, save_pass2, \\\n+                    n_reads, n_bp, written_reads, written_bp\n+\n+            # we want to track paired reads here, to make sure that pairs\n+            # are not split between first pass and second pass.\n+\n+            if is_pair:\n+                n_reads += 2\n+                n_bp += len(read1.sequence) + len(read2.sequence)\n+\n+                seq1 = read1.sequence.replace('N', 'A')\n+                seq2 = read2.sequence.replace('N', 'A')\n+\n+                med1, _, _ = ct.get_median_count(seq1)\n+                med2, _, _ = ct.get_median_count(seq2)\n+\n+                if med1 < NORMALIZE_LIMIT or med2 < NORMALIZE_LIMIT:\n+                    ct.consume(seq1)\n+                    ct.consume(seq2)\n+                    write_record_pair(read1, read2, pass2fp)\n+                    save_pass2 += 2\n+                else:\n+                    _, trim_at1 = ct.trim_on_abundance(seq1, CUTOFF)\n+                    _, trim_at2 = ct.trim_on_abundance(seq2, CUTOFF)\n+\n+                    if trim_at1 >= K:\n+                        read1 = trim_record(read1, trim_at1)\n+\n+                    if trim_at2 >= K:\n+                        read2 = trim_record(read2, trim_at2)\n+\n+                    if trim_at1 != len(seq1):\n+                        trimmed_reads += 1\n+                    if trim_at2 != len(seq2):\n+                        trimmed_reads += 1\n+\n+                    write_record_pair(read1, read2, trimfp)\n+                    written_reads += 2\n+                    written_bp += trim_at1 + trim_at2\n+            else:\n+                n_reads += 1\n+                n_bp += len(read1.sequence)\n+\n+                seq = read1.sequence.replace('N', 'A')\n+                med, _, _ = ct.get_median_count(seq)\n+\n+                # has this portion of the graph saturated? if not,\n+                # consume & save => pass2.\n+                if med < NORMALIZE_LIMIT:\n+                    ct.consume(seq)\n+                    write_record(read1, pass2fp)\n+                    save_pass2 += 1\n+                else:                       # trim!!\n+                    _, trim_at = ct.trim_on_abundance(seq, CUTOFF)\n+                    if trim_at >= K:\n+                        new_read = trim_record(read1, trim_at)\n+                        write_record(new_read, trimfp)\n+\n+                        written_reads += 1\n+                        written_bp += trim_at\n+\n+                        if trim_at != len(read1.sequence):\n+                            trimmed_reads += 1\n+\n+        pass2fp.close()\n+        trimfp.close()\n+\n+        print '%s: kept aside %d of %d from first pass, in %s' % \\\n+              (filename, save_pass2, n, filename)\n+        save_pass2_total += save_pass2\n+\n+    # ### SECOND PASS. ###\n+\n+    skipped_n = 0\n+    skipped_bp = 0\n+    for orig_filename, pass2filename, trimfilename in pass2list:\n+        print 'second pass: looking at sequences kept aside in %s' % \\\n+              pass2filename\n+\n+        # note that for this second pass, we don't care about paired\n+        # reads - they will be output in the same order they're read in,\n+        # so pairs will stay together if not orphaned.  This is in contrast\n+        # to the first loop.\n+\n+        trimfp = open(trimfilename, 'a')\n+        for n, read in enumerate(screed.open(pass2filename)):\n+            if n % 10000 == 0:\n+                print >>sys.stderr, '... x 2', n, pass2filename, \\\n+                    written_reads, written_bp\n+\n+            seq = read.sequence.replace('N', 'A')\n+            med, _, _ = ct.get_median_count(seq)\n+\n+            # do we retain low-abundance components unchanged?\n+            if med < NORMALIZE_LIMIT and args.variable_coverage:\n+                write_record(read, trimfp)\n+\n+                written_reads += 1\n+                written_bp += len(read.sequence)\n+                skipped_n += 1\n+                skipped_bp += len(read.sequence)\n+\n+            # otherwise, examine/trim/truncate.\n+            else:    # med >= NORMALIZE LIMIT or not args.variable_coverage\n+                _, trim_at = ct.trim_on_abundance(seq, CUTOFF)\n+                if trim_at >= K:\n+                    new_read = trim_record(read, trim_at)\n+                    write_record(new_read, trimfp)\n+\n+                    written_reads += 1\n+                    written_bp += trim_at\n+\n+                    if trim_at != len(read.sequence):\n+                        trimmed_reads += 1\n+\n+        print >>sys.stderr, 'removing %s' % pass2filename\n+        os.unlink(pass2filename)\n+\n+    print >>sys.stderr, 'removing temp directory & contents (%s)' % tempdir\n+    shutil.rmtree(tempdir)\n+\n+    print 'read %d reads, %d bp' % (n_reads, n_bp,)\n+    print 'wrote %d reads, %d bp' % (written_reads, written_bp,)\n+    print 'removed %d reads and trimmed %d reads' % (n_reads - written_reads,\n+                                                     trimmed_reads,)\n+    print 'looked at %d reads twice' % (save_pass2_total,)\n+    print 'trimmed or removed %.2f%% of bases (%d total)' % \\\n+        ((1 - (written_bp / float(n_bp))) * 100., n_bp - written_bp)\n+\n+    if args.variable_coverage:\n+        print 'skipped %d reads/%d bases because of low coverage' % \\\n+              (skipped_n, skipped_bp)\n+\n+    fp_rate = khmer.calc_expected_collisions(ct)\n+    print >>sys.stderr, \\\n+        'fp rate estimated to be {fpr:1.3f}'.format(fpr=fp_rate)\n+\n+    if fp_rate > MAX_FALSE_POSITIVE_RATE:\n+        print >> sys.stderr, \"**\"\n+        print >> sys.stderr, (\"** ERROR: the k-mer counting table is too small\"\n+                              \" for this data set. Increase tablesize/# \"\n+                              \"tables.\")\n+        print >> sys.stderr, \"**\"\n+        print >> sys.stderr, \"** Do not use these results!!\"","path":"scripts/trim-low-abund.py","position":288,"original_position":288,"commit_id":"216fa57925ae4571791cd9f61e9595b627892db7","original_commit_id":"216fa57925ae4571791cd9f61e9595b627892db7","user":{"login":"mr-c","id":1330696,"avatar_url":"https://avatars.githubusercontent.com/u/1330696?v=3","gravatar_id":"","url":"https://api.github.com/users/mr-c","html_url":"https://github.com/mr-c","followers_url":"https://api.github.com/users/mr-c/followers","following_url":"https://api.github.com/users/mr-c/following{/other_user}","gists_url":"https://api.github.com/users/mr-c/gists{/gist_id}","starred_url":"https://api.github.com/users/mr-c/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mr-c/subscriptions","organizations_url":"https://api.github.com/users/mr-c/orgs","repos_url":"https://api.github.com/users/mr-c/repos","events_url":"https://api.github.com/users/mr-c/events{/privacy}","received_events_url":"https://api.github.com/users/mr-c/received_events","type":"User","site_admin":false},"body":"No test coverage for this branch","created_at":"2015-02-11T17:33:38Z","updated_at":"2015-02-11T17:33:38Z","html_url":"https://github.com/ged-lab/khmer/pull/759#discussion_r24514536","pull_request_url":"https://api.github.com/repos/ged-lab/khmer/pulls/759","_links":{"self":{"href":"https://api.github.com/repos/ged-lab/khmer/pulls/comments/24514536"},"html":{"href":"https://github.com/ged-lab/khmer/pull/759#discussion_r24514536"},"pull_request":{"href":"https://api.github.com/repos/ged-lab/khmer/pulls/759"}}},"pull_request":{"url":"https://api.github.com/repos/ged-lab/khmer/pulls/759","id":28863496,"html_url":"https://github.com/ged-lab/khmer/pull/759","diff_url":"https://github.com/ged-lab/khmer/pull/759.diff","patch_url":"https://github.com/ged-lab/khmer/pull/759.patch","issue_url":"https://api.github.com/repos/ged-lab/khmer/issues/759","number":759,"state":"open","locked":false,"title":"\"broken\" paired-read support for a few scripts","user":{"login":"ctb","id":51016,"avatar_url":"https://avatars.githubusercontent.com/u/51016?v=3","gravatar_id":"","url":"https://api.github.com/users/ctb","html_url":"https://github.com/ctb","followers_url":"https://api.github.com/users/ctb/followers","following_url":"https://api.github.com/users/ctb/following{/other_user}","gists_url":"https://api.github.com/users/ctb/gists{/gist_id}","starred_url":"https://api.github.com/users/ctb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctb/subscriptions","organizations_url":"https://api.github.com/users/ctb/orgs","repos_url":"https://api.github.com/users/ctb/repos","events_url":"https://api.github.com/users/ctb/events{/privacy}","received_events_url":"https://api.github.com/users/ctb/received_events","type":"User","site_admin":false},"body":"Ref #733. Should address #754. Fixes #758, too.\r\n","created_at":"2015-02-07T12:14:13Z","updated_at":"2015-02-11T17:33:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0ed4030b014bb334fa0c4ccb3b77c3d4fb462909","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ged-lab/khmer/pulls/759/commits","review_comments_url":"https://api.github.com/repos/ged-lab/khmer/pulls/759/comments","review_comment_url":"https://api.github.com/repos/ged-lab/khmer/pulls/comments/{number}","comments_url":"https://api.github.com/repos/ged-lab/khmer/issues/759/comments","statuses_url":"https://api.github.com/repos/ged-lab/khmer/statuses/216fa57925ae4571791cd9f61e9595b627892db7","head":{"label":"ged-lab:update/trim_low_abund","ref":"update/trim_low_abund","sha":"216fa57925ae4571791cd9f61e9595b627892db7","user":{"login":"ged-lab","id":1740697,"avatar_url":"https://avatars.githubusercontent.com/u/1740697?v=3","gravatar_id":"","url":"https://api.github.com/users/ged-lab","html_url":"https://github.com/ged-lab","followers_url":"https://api.github.com/users/ged-lab/followers","following_url":"https://api.github.com/users/ged-lab/following{/other_user}","gists_url":"https://api.github.com/users/ged-lab/gists{/gist_id}","starred_url":"https://api.github.com/users/ged-lab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ged-lab/subscriptions","organizations_url":"https://api.github.com/users/ged-lab/orgs","repos_url":"https://api.github.com/users/ged-lab/repos","events_url":"https://api.github.com/users/ged-lab/events{/privacy}","received_events_url":"https://api.github.com/users/ged-lab/received_events","type":"Organization","site_admin":false},"repo":{"id":4331833,"name":"khmer","full_name":"ged-lab/khmer","owner":{"login":"ged-lab","id":1740697,"avatar_url":"https://avatars.githubusercontent.com/u/1740697?v=3","gravatar_id":"","url":"https://api.github.com/users/ged-lab","html_url":"https://github.com/ged-lab","followers_url":"https://api.github.com/users/ged-lab/followers","following_url":"https://api.github.com/users/ged-lab/following{/other_user}","gists_url":"https://api.github.com/users/ged-lab/gists{/gist_id}","starred_url":"https://api.github.com/users/ged-lab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ged-lab/subscriptions","organizations_url":"https://api.github.com/users/ged-lab/orgs","repos_url":"https://api.github.com/users/ged-lab/repos","events_url":"https://api.github.com/users/ged-lab/events{/privacy}","received_events_url":"https://api.github.com/users/ged-lab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ged-lab/khmer","description":"In-memory nucleotide sequence k-mer counting, filtering, graph traversal and more","fork":false,"url":"https://api.github.com/repos/ged-lab/khmer","forks_url":"https://api.github.com/repos/ged-lab/khmer/forks","keys_url":"https://api.github.com/repos/ged-lab/khmer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ged-lab/khmer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ged-lab/khmer/teams","hooks_url":"https://api.github.com/repos/ged-lab/khmer/hooks","issue_events_url":"https://api.github.com/repos/ged-lab/khmer/issues/events{/number}","events_url":"https://api.github.com/repos/ged-lab/khmer/events","assignees_url":"https://api.github.com/repos/ged-lab/khmer/assignees{/user}","branches_url":"https://api.github.com/repos/ged-lab/khmer/branches{/branch}","tags_url":"https://api.github.com/repos/ged-lab/khmer/tags","blobs_url":"https://api.github.com/repos/ged-lab/khmer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ged-lab/khmer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ged-lab/khmer/git/refs{/sha}","trees_url":"https://api.github.com/repos/ged-lab/khmer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ged-lab/khmer/statuses/{sha}","languages_url":"https://api.github.com/repos/ged-lab/khmer/languages","stargazers_url":"https://api.github.com/repos/ged-lab/khmer/stargazers","contributors_url":"https://api.github.com/repos/ged-lab/khmer/contributors","subscribers_url":"https://api.github.com/repos/ged-lab/khmer/subscribers","subscription_url":"https://api.github.com/repos/ged-lab/khmer/subscription","commits_url":"https://api.github.com/repos/ged-lab/khmer/commits{/sha}","git_commits_url":"https://api.github.com/repos/ged-lab/khmer/git/commits{/sha}","comments_url":"https://api.github.com/repos/ged-lab/khmer/comments{/number}","issue_comment_url":"https://api.github.com/repos/ged-lab/khmer/issues/comments/{number}","contents_url":"https://api.github.com/repos/ged-lab/khmer/contents/{+path}","compare_url":"https://api.github.com/repos/ged-lab/khmer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ged-lab/khmer/merges","archive_url":"https://api.github.com/repos/ged-lab/khmer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ged-lab/khmer/downloads","issues_url":"https://api.github.com/repos/ged-lab/khmer/issues{/number}","pulls_url":"https://api.github.com/repos/ged-lab/khmer/pulls{/number}","milestones_url":"https://api.github.com/repos/ged-lab/khmer/milestones{/number}","notifications_url":"https://api.github.com/repos/ged-lab/khmer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ged-lab/khmer/labels{/name}","releases_url":"https://api.github.com/repos/ged-lab/khmer/releases{/id}","created_at":"2012-05-15T03:52:53Z","updated_at":"2015-02-11T16:13:38Z","pushed_at":"2015-02-11T16:54:41Z","git_url":"git://github.com/ged-lab/khmer.git","ssh_url":"git@github.com:ged-lab/khmer.git","clone_url":"https://github.com/ged-lab/khmer.git","svn_url":"https://github.com/ged-lab/khmer","homepage":"http://khmer.readthedocs.org/","size":148643,"stargazers_count":199,"watchers_count":199,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":150,"mirror_url":null,"open_issues_count":229,"forks":150,"open_issues":229,"watchers":199,"default_branch":"master"}},"base":{"label":"ged-lab:master","ref":"master","sha":"b71158beccedafd5e0b8daf21108cf9da727fef6","user":{"login":"ged-lab","id":1740697,"avatar_url":"https://avatars.githubusercontent.com/u/1740697?v=3","gravatar_id":"","url":"https://api.github.com/users/ged-lab","html_url":"https://github.com/ged-lab","followers_url":"https://api.github.com/users/ged-lab/followers","following_url":"https://api.github.com/users/ged-lab/following{/other_user}","gists_url":"https://api.github.com/users/ged-lab/gists{/gist_id}","starred_url":"https://api.github.com/users/ged-lab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ged-lab/subscriptions","organizations_url":"https://api.github.com/users/ged-lab/orgs","repos_url":"https://api.github.com/users/ged-lab/repos","events_url":"https://api.github.com/users/ged-lab/events{/privacy}","received_events_url":"https://api.github.com/users/ged-lab/received_events","type":"Organization","site_admin":false},"repo":{"id":4331833,"name":"khmer","full_name":"ged-lab/khmer","owner":{"login":"ged-lab","id":1740697,"avatar_url":"https://avatars.githubusercontent.com/u/1740697?v=3","gravatar_id":"","url":"https://api.github.com/users/ged-lab","html_url":"https://github.com/ged-lab","followers_url":"https://api.github.com/users/ged-lab/followers","following_url":"https://api.github.com/users/ged-lab/following{/other_user}","gists_url":"https://api.github.com/users/ged-lab/gists{/gist_id}","starred_url":"https://api.github.com/users/ged-lab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ged-lab/subscriptions","organizations_url":"https://api.github.com/users/ged-lab/orgs","repos_url":"https://api.github.com/users/ged-lab/repos","events_url":"https://api.github.com/users/ged-lab/events{/privacy}","received_events_url":"https://api.github.com/users/ged-lab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ged-lab/khmer","description":"In-memory nucleotide sequence k-mer counting, filtering, graph traversal and more","fork":false,"url":"https://api.github.com/repos/ged-lab/khmer","forks_url":"https://api.github.com/repos/ged-lab/khmer/forks","keys_url":"https://api.github.com/repos/ged-lab/khmer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ged-lab/khmer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ged-lab/khmer/teams","hooks_url":"https://api.github.com/repos/ged-lab/khmer/hooks","issue_events_url":"https://api.github.com/repos/ged-lab/khmer/issues/events{/number}","events_url":"https://api.github.com/repos/ged-lab/khmer/events","assignees_url":"https://api.github.com/repos/ged-lab/khmer/assignees{/user}","branches_url":"https://api.github.com/repos/ged-lab/khmer/branches{/branch}","tags_url":"https://api.github.com/repos/ged-lab/khmer/tags","blobs_url":"https://api.github.com/repos/ged-lab/khmer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ged-lab/khmer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ged-lab/khmer/git/refs{/sha}","trees_url":"https://api.github.com/repos/ged-lab/khmer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ged-lab/khmer/statuses/{sha}","languages_url":"https://api.github.com/repos/ged-lab/khmer/languages","stargazers_url":"https://api.github.com/repos/ged-lab/khmer/stargazers","contributors_url":"https://api.github.com/repos/ged-lab/khmer/contributors","subscribers_url":"https://api.github.com/repos/ged-lab/khmer/subscribers","subscription_url":"https://api.github.com/repos/ged-lab/khmer/subscription","commits_url":"https://api.github.com/repos/ged-lab/khmer/commits{/sha}","git_commits_url":"https://api.github.com/repos/ged-lab/khmer/git/commits{/sha}","comments_url":"https://api.github.com/repos/ged-lab/khmer/comments{/number}","issue_comment_url":"https://api.github.com/repos/ged-lab/khmer/issues/comments/{number}","contents_url":"https://api.github.com/repos/ged-lab/khmer/contents/{+path}","compare_url":"https://api.github.com/repos/ged-lab/khmer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ged-lab/khmer/merges","archive_url":"https://api.github.com/repos/ged-lab/khmer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ged-lab/khmer/downloads","issues_url":"https://api.github.com/repos/ged-lab/khmer/issues{/number}","pulls_url":"https://api.github.com/repos/ged-lab/khmer/pulls{/number}","milestones_url":"https://api.github.com/repos/ged-lab/khmer/milestones{/number}","notifications_url":"https://api.github.com/repos/ged-lab/khmer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ged-lab/khmer/labels{/name}","releases_url":"https://api.github.com/repos/ged-lab/khmer/releases{/id}","created_at":"2012-05-15T03:52:53Z","updated_at":"2015-02-11T16:13:38Z","pushed_at":"2015-02-11T16:54:41Z","git_url":"git://github.com/ged-lab/khmer.git","ssh_url":"git@github.com:ged-lab/khmer.git","clone_url":"https://github.com/ged-lab/khmer.git","svn_url":"https://github.com/ged-lab/khmer","homepage":"http://khmer.readthedocs.org/","size":148643,"stargazers_count":199,"watchers_count":199,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":150,"mirror_url":null,"open_issues_count":229,"forks":150,"open_issues":229,"watchers":199,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ged-lab/khmer/pulls/759"},"html":{"href":"https://github.com/ged-lab/khmer/pull/759"},"issue":{"href":"https://api.github.com/repos/ged-lab/khmer/issues/759"},"comments":{"href":"https://api.github.com/repos/ged-lab/khmer/issues/759/comments"},"review_comments":{"href":"https://api.github.com/repos/ged-lab/khmer/pulls/759/comments"},"review_comment":{"href":"https://api.github.com/repos/ged-lab/khmer/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/ged-lab/khmer/pulls/759/commits"},"statuses":{"href":"https://api.github.com/repos/ged-lab/khmer/statuses/216fa57925ae4571791cd9f61e9595b627892db7"}}}}