{"action":"created","comment":{"url":"https://api.github.com/repos/bendalab/thunderfish/pulls/comments/61569519","id":61569519,"diff_hunk":"@@ -0,0 +1,355 @@\n+import os.path\n+import numpy as np\n+\n+\"\"\"\n+Numerous functions for loading data from audio files.\n+\n+data, samplingrate = load_audio(filepath)\n+tries different functions until it succeeds to load the data.\n+\n+For an overview on available python modules see\n+http://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/audio-files/index.ipynb\n+\"\"\"\n+ \n+def load_wave(filename, verbose=0) :\n+    \"\"\"\n+    Load wav file using wave module (from pythons standard libray).\n+    Documentation: https://docs.python.org/2/library/wave.html\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages\n+                       if 2 print information about soundfile\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the wave module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        import wave\n+    except ImportError:\n+        print 'python module \"wave\" is not installed.'\n+        raise ImportError\n+\n+    wf = wave.open(filename, 'r')   # 'with' is not supported by wave\n+    (nchannels, sampwidth, rate, nframes, comptype, compname) = wf.getparams()\n+    if verbose > 1 :\n+        print('channels        : %d' % nchannels)\n+        print('bytes           : %d' % sampwidth)\n+        print('sampling rate   : %g' % rate)\n+        print('frames          : %d' % nframes)\n+        print('compression type: %s' % comptype)\n+        print('compression name: %s' % compname)\n+    buffer = wf.readframes(nframes)\n+    format = 'i%d' % sampwidth\n+    data = np.fromstring(buffer, dtype=format).reshape(-1, nchannels)  # read data\n+    wf.close()\n+    data /= 2.0**(sampwidth*8-1)\n+    if len(data.shape) == 1 :\n+        data = np.reshape(data,(-1, 1))\n+    return data, float(rate)\n+\n+    \n+def load_ewave(filename, verbose=0) :\n+    \"\"\"\n+    Load wav file using ewave module.\n+    https://github.com/melizalab/py-ewave\n+    Installation:\n+    git clone https://github.com/melizalab/py-ewave\n+    python setup.py build\n+    sudo python setup.py install\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages (not used)\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the ewave module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        import ewave\n+    except ImportError:\n+        print 'python module \"ewave\" is not installed.'\n+        raise ImportError\n+\n+    data = np.array([])\n+    rate = 0.0\n+    with ewave.open(filename, 'r') as wf :\n+        rate = wf.sampling_rate\n+        buffer = wf.read()\n+        data = ewave.rescale(buffer, 'float')\n+    if len(data.shape) == 1 :\n+        data = np.reshape(data,(-1, 1))\n+    return data, float(rate)\n+\n+    \n+def load_wavfile(filename, verbose=0) :\n+    \"\"\"\n+    Load wav file using scipy.io.wavfile.\n+    Documentation: http://docs.scipy.org/doc/scipy/reference/io.html\n+    \n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the scipy.io module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        from scipy.io import wavfile\n+    except ImportError:\n+        print 'python module \"scipy.io\" is not installed.'\n+        raise ImportError\n+\n+    if verbose < 2 :\n+        warnings.filterwarnings(\"ignore\")\n+    rate, data = wavfile.read(filename)\n+    if verbose < 2 :\n+        warnings.filterwarnings(\"always\")\n+    data /= 2.0**15\n+    if len(data.shape) == 1 :\n+        data = np.reshape(data,(-1, 1))\n+    return data, float(rate)\n+        \n+\n+def load_soundfile(filename, verbose=0) :\n+    \"\"\"\n+    Load audio file using pysoundfile (based on libsndfile).\n+\n+    Installation of pysoundfile:\n+    sudo apt-get install libffi-dev\n+    sudo pip install pysoundfile\n+    For documentation see http://pysoundfile.readthedocs.org .\n+    Block processing is possible.\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages (not used)\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the soundfile module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        import soundfile\n+    except ImportError:\n+        print 'python module \"soundfile\" is not installed.'\n+        raise ImportError\n+\n+    data = np.array([])\n+    rate = 0.0\n+    with soundfile.SoundFile(filename, 'r') as sf :\n+        rate = sf.samplerate\n+        data = sf.read(always_2d=True)\n+    return data, float(rate)\n+\n+\n+def load_wavefile(filename, verbose=0) :\n+    \"\"\"\n+    Load audio file using wavefile (based on libsndfile).\n+\n+    Installation: sudo pip install wavefile\n+    Website: https://github.com/vokimon/python-wavefile\n+    Block processing is possible.\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages (not used)\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the wavefile module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        import wavefile\n+    except ImportError:\n+        print 'python module \"wavefile\" is not installed.'\n+        raise ImportError\n+\n+    rate, data = wavefile.load(filename)\n+    return data.T, float(rate)\n+\n+\n+def load_audiolab(filename, verbose=0) :\n+    \"\"\"\n+    Load audio file using scikits.audiolab (based on libsndfile).\n+\n+    Installation: sudo pip install scikits.audiolab\n+    Website: http://cournape.github.io/audiolab/\n+    Block processing is possible.\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages (not used)\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the scikits.audiolab module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        import scikits.audiolab as audiolab\n+    except ImportError:\n+        print 'python module \"scikits.audiolab\" is not installed.'\n+        raise ImportError\n+\n+    af = audiolab.Sndfile(filename)\n+    rate = af.samplerate\n+    data = af.read_frames(af.nframes)\n+    if len(data.shape) == 1 :\n+        data = np.reshape(data,(-1, 1))\n+    return data, float(rate)\n+\n+\n+def load_audioread(filename, verbose=0) :\n+    \"\"\"\n+    Load audio file using audioread.\n+    https://github.com/sampsyo/audioread\n+    This is not available in python x,y.\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages (not used)\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+\n+    Exceptions:\n+        ImportError: if the audioread module is not installed\n+        *: if loading of the data failed\n+    \"\"\"\n+    try:\n+        import audioread\n+    except ImportError:\n+        print 'python module \"audioread\" is not installed.'\n+        raise ImportError\n+    \n+    data = np.array([])\n+    rate = 0.0\n+    with audioread.audio_open(filename) as af :\n+        rate = af.samplerate\n+        data = np.zeros((np.ceil(af.samplerate*af.duration), af.channels),\n+                        dtype=\"<i2\")\n+        index = 0\n+        for buffer in af:\n+            fulldata = np.fromstring(buffer, dtype='<i2').reshape(-1, af.channels)\n+            n = fulldata.shape[0]\n+            if index+n > len( data ) :\n+                n = len( data ) - index\n+            if n > 0 :\n+                data[index:index+n,:] = fulldata[:n,:]\n+                index += n\n+            else :\n+                break\n+    return data/2.0**15, float(rate)\n+\n+\n+audio_loader = [\n+    ['wave', load_wave],\n+    ['scipy.io.wavfile', load_wavfile],\n+    ['soundfile', load_soundfile],\n+    ['audioread', load_audioread],\n+    ['scikits.audiolab', load_audiolab],\n+    ['ewave', load_ewave],\n+    ['wavefile', load_wavefile]\n+    ]\n+\n+def load_audio(filepath, verbose=0) :\n+    \"\"\"\n+    Call this function to load all channels of audio data from a file.\n+    This function tries different python modules to load the audio file.\n+\n+    Args:\n+        filepath (string): the full path and name of the file to load\n+        verbose (int): if >0 show detailed error/warning messages\n+\n+    Returns:\n+        data (array): all data traces as an 2-D numpy array,\n+                      first dimension is time, second is channel\n+        rate (float): the sampling rate of the data in Hz\n+    \"\"\"\n+    # check types:\n+    if not isinstance(filepath, basestring) :\n+        raise NameError('load_audio(): input argument filepath must be a string!')\n+\n+    # check values:\n+    rate = 0.0\n+    data = np.array([])\n+    if len(filepath) == 0 :\n+        print('load_audio(): input argument filepath is empty string!')\n+        return data, rate\n+    if not os.path.isfile(filepath) :\n+        print('load_audio(): input argument filepath=%s does not indicate an existing file!' % filepath)\n+        return data, rate\n+    if os.path.getsize(filepath) <= 0:\n+        print('load_audio(): input argument filepath=%s indicates file of size 0!' % filepath)\n+        return data, rate\n+\n+    # load data:\n+    # load an audio file by trying various modules:\n+    for lib, load_file in audio_loader :\n+        try:\n+            data, rate = load_file(filepath, verbose)\n+            if len(data) > 0 :\n+                if verbose > 0 :\n+                    print('loaded data from file \"%s\" using %s:' %\n+                          (filepath, lib))\n+                    print('  sampling rate: %g Hz' % rate)\n+                    print('  data values  : %d' % len(data))\n+                break\n+        except:\n+            if verbose > 0 :\n+                print('failed to load data from file \"%s\" with %s' %\n+                      (filepath, lib))\n+    return data, rate\n+\n+\n+if __name__ == \"__main__\":\n+    import sys\n+    print(\"Checking audioloader module ...\")\n+    filepath = sys.argv[-1]\n+    print\n+    print(\"try load_audio:\")\n+    data, rate = load_audio(filepath, 2)\n+    print","path":"thunderfish/audioloader.py","position":347,"original_position":347,"commit_id":"93fa1fff3863df3d57baf17fd2d2ee528323726b","original_commit_id":"93fa1fff3863df3d57baf17fd2d2ee528323726b","user":{"login":"jgrewe","id":772522,"avatar_url":"https://avatars.githubusercontent.com/u/772522?v=3","gravatar_id":"","url":"https://api.github.com/users/jgrewe","html_url":"https://github.com/jgrewe","followers_url":"https://api.github.com/users/jgrewe/followers","following_url":"https://api.github.com/users/jgrewe/following{/other_user}","gists_url":"https://api.github.com/users/jgrewe/gists{/gist_id}","starred_url":"https://api.github.com/users/jgrewe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jgrewe/subscriptions","organizations_url":"https://api.github.com/users/jgrewe/orgs","repos_url":"https://api.github.com/users/jgrewe/repos","events_url":"https://api.github.com/users/jgrewe/events{/privacy}","received_events_url":"https://api.github.com/users/jgrewe/received_events","type":"User","site_admin":false},"body":"is this py3 compatible","created_at":"2016-04-29T12:33:31Z","updated_at":"2016-04-29T12:33:31Z","html_url":"https://github.com/bendalab/thunderfish/pull/24#discussion_r61569519","pull_request_url":"https://api.github.com/repos/bendalab/thunderfish/pulls/24","_links":{"self":{"href":"https://api.github.com/repos/bendalab/thunderfish/pulls/comments/61569519"},"html":{"href":"https://github.com/bendalab/thunderfish/pull/24#discussion_r61569519"},"pull_request":{"href":"https://api.github.com/repos/bendalab/thunderfish/pulls/24"}}},"pull_request":{"url":"https://api.github.com/repos/bendalab/thunderfish/pulls/24","id":68362936,"html_url":"https://github.com/bendalab/thunderfish/pull/24","diff_url":"https://github.com/bendalab/thunderfish/pull/24.diff","patch_url":"https://github.com/bendalab/thunderfish/pull/24.patch","issue_url":"https://api.github.com/repos/bendalab/thunderfish/issues/24","number":24,"state":"open","locked":false,"title":"modularized best_window, detect_peaks, load_data, load_audio","user":{"login":"janscience","id":12050052,"avatar_url":"https://avatars.githubusercontent.com/u/12050052?v=3","gravatar_id":"","url":"https://api.github.com/users/janscience","html_url":"https://github.com/janscience","followers_url":"https://api.github.com/users/janscience/followers","following_url":"https://api.github.com/users/janscience/following{/other_user}","gists_url":"https://api.github.com/users/janscience/gists{/gist_id}","starred_url":"https://api.github.com/users/janscience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/janscience/subscriptions","organizations_url":"https://api.github.com/users/janscience/orgs","repos_url":"https://api.github.com/users/janscience/repos","events_url":"https://api.github.com/users/janscience/events{/privacy}","received_events_url":"https://api.github.com/users/janscience/received_events","type":"User","site_admin":false},"body":"New modules audioloader.py, dataloader.py, peakdetection.py, bestwindow.py, and bestwindowplots.py \r\nwith heavily improved code and documentation. See their __main__ code for usage and run it for demos. bestwindowplots.py can be called with a name of a wav-file recording. Please update the thunderfish code to use those function and erase the equivalent old stuff.","created_at":"2016-04-29T12:19:11Z","updated_at":"2016-04-29T12:33:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"16c979650be66582233ac1b734a9b15199869c10","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/bendalab/thunderfish/pulls/24/commits","review_comments_url":"https://api.github.com/repos/bendalab/thunderfish/pulls/24/comments","review_comment_url":"https://api.github.com/repos/bendalab/thunderfish/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bendalab/thunderfish/issues/24/comments","statuses_url":"https://api.github.com/repos/bendalab/thunderfish/statuses/93fa1fff3863df3d57baf17fd2d2ee528323726b","head":{"label":"janscience:master","ref":"master","sha":"93fa1fff3863df3d57baf17fd2d2ee528323726b","user":{"login":"janscience","id":12050052,"avatar_url":"https://avatars.githubusercontent.com/u/12050052?v=3","gravatar_id":"","url":"https://api.github.com/users/janscience","html_url":"https://github.com/janscience","followers_url":"https://api.github.com/users/janscience/followers","following_url":"https://api.github.com/users/janscience/following{/other_user}","gists_url":"https://api.github.com/users/janscience/gists{/gist_id}","starred_url":"https://api.github.com/users/janscience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/janscience/subscriptions","organizations_url":"https://api.github.com/users/janscience/orgs","repos_url":"https://api.github.com/users/janscience/repos","events_url":"https://api.github.com/users/janscience/events{/privacy}","received_events_url":"https://api.github.com/users/janscience/received_events","type":"User","site_admin":false},"repo":{"id":55062948,"name":"thunderfish","full_name":"janscience/thunderfish","owner":{"login":"janscience","id":12050052,"avatar_url":"https://avatars.githubusercontent.com/u/12050052?v=3","gravatar_id":"","url":"https://api.github.com/users/janscience","html_url":"https://github.com/janscience","followers_url":"https://api.github.com/users/janscience/followers","following_url":"https://api.github.com/users/janscience/following{/other_user}","gists_url":"https://api.github.com/users/janscience/gists{/gist_id}","starred_url":"https://api.github.com/users/janscience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/janscience/subscriptions","organizations_url":"https://api.github.com/users/janscience/orgs","repos_url":"https://api.github.com/users/janscience/repos","events_url":"https://api.github.com/users/janscience/events{/privacy}","received_events_url":"https://api.github.com/users/janscience/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/janscience/thunderfish","description":"python scripts for analyzing recordings of efish electric fields.","fork":true,"url":"https://api.github.com/repos/janscience/thunderfish","forks_url":"https://api.github.com/repos/janscience/thunderfish/forks","keys_url":"https://api.github.com/repos/janscience/thunderfish/keys{/key_id}","collaborators_url":"https://api.github.com/repos/janscience/thunderfish/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/janscience/thunderfish/teams","hooks_url":"https://api.github.com/repos/janscience/thunderfish/hooks","issue_events_url":"https://api.github.com/repos/janscience/thunderfish/issues/events{/number}","events_url":"https://api.github.com/repos/janscience/thunderfish/events","assignees_url":"https://api.github.com/repos/janscience/thunderfish/assignees{/user}","branches_url":"https://api.github.com/repos/janscience/thunderfish/branches{/branch}","tags_url":"https://api.github.com/repos/janscience/thunderfish/tags","blobs_url":"https://api.github.com/repos/janscience/thunderfish/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/janscience/thunderfish/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/janscience/thunderfish/git/refs{/sha}","trees_url":"https://api.github.com/repos/janscience/thunderfish/git/trees{/sha}","statuses_url":"https://api.github.com/repos/janscience/thunderfish/statuses/{sha}","languages_url":"https://api.github.com/repos/janscience/thunderfish/languages","stargazers_url":"https://api.github.com/repos/janscience/thunderfish/stargazers","contributors_url":"https://api.github.com/repos/janscience/thunderfish/contributors","subscribers_url":"https://api.github.com/repos/janscience/thunderfish/subscribers","subscription_url":"https://api.github.com/repos/janscience/thunderfish/subscription","commits_url":"https://api.github.com/repos/janscience/thunderfish/commits{/sha}","git_commits_url":"https://api.github.com/repos/janscience/thunderfish/git/commits{/sha}","comments_url":"https://api.github.com/repos/janscience/thunderfish/comments{/number}","issue_comment_url":"https://api.github.com/repos/janscience/thunderfish/issues/comments{/number}","contents_url":"https://api.github.com/repos/janscience/thunderfish/contents/{+path}","compare_url":"https://api.github.com/repos/janscience/thunderfish/compare/{base}...{head}","merges_url":"https://api.github.com/repos/janscience/thunderfish/merges","archive_url":"https://api.github.com/repos/janscience/thunderfish/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/janscience/thunderfish/downloads","issues_url":"https://api.github.com/repos/janscience/thunderfish/issues{/number}","pulls_url":"https://api.github.com/repos/janscience/thunderfish/pulls{/number}","milestones_url":"https://api.github.com/repos/janscience/thunderfish/milestones{/number}","notifications_url":"https://api.github.com/repos/janscience/thunderfish/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/janscience/thunderfish/labels{/name}","releases_url":"https://api.github.com/repos/janscience/thunderfish/releases{/id}","deployments_url":"https://api.github.com/repos/janscience/thunderfish/deployments","created_at":"2016-03-30T12:55:40Z","updated_at":"2016-03-30T12:55:42Z","pushed_at":"2016-04-29T12:14:36Z","git_url":"git://github.com/janscience/thunderfish.git","ssh_url":"git@github.com:janscience/thunderfish.git","clone_url":"https://github.com/janscience/thunderfish.git","svn_url":"https://github.com/janscience/thunderfish","homepage":null,"size":410,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"bendalab:master","ref":"master","sha":"9cc1064f72c8b070a680b2716637308110307190","user":{"login":"bendalab","id":10567758,"avatar_url":"https://avatars.githubusercontent.com/u/10567758?v=3","gravatar_id":"","url":"https://api.github.com/users/bendalab","html_url":"https://github.com/bendalab","followers_url":"https://api.github.com/users/bendalab/followers","following_url":"https://api.github.com/users/bendalab/following{/other_user}","gists_url":"https://api.github.com/users/bendalab/gists{/gist_id}","starred_url":"https://api.github.com/users/bendalab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bendalab/subscriptions","organizations_url":"https://api.github.com/users/bendalab/orgs","repos_url":"https://api.github.com/users/bendalab/repos","events_url":"https://api.github.com/users/bendalab/events{/privacy}","received_events_url":"https://api.github.com/users/bendalab/received_events","type":"Organization","site_admin":false},"repo":{"id":50343080,"name":"thunderfish","full_name":"bendalab/thunderfish","owner":{"login":"bendalab","id":10567758,"avatar_url":"https://avatars.githubusercontent.com/u/10567758?v=3","gravatar_id":"","url":"https://api.github.com/users/bendalab","html_url":"https://github.com/bendalab","followers_url":"https://api.github.com/users/bendalab/followers","following_url":"https://api.github.com/users/bendalab/following{/other_user}","gists_url":"https://api.github.com/users/bendalab/gists{/gist_id}","starred_url":"https://api.github.com/users/bendalab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bendalab/subscriptions","organizations_url":"https://api.github.com/users/bendalab/orgs","repos_url":"https://api.github.com/users/bendalab/repos","events_url":"https://api.github.com/users/bendalab/events{/privacy}","received_events_url":"https://api.github.com/users/bendalab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bendalab/thunderfish","description":"python scripts for analyzing recordings of efish electric fields.","fork":false,"url":"https://api.github.com/repos/bendalab/thunderfish","forks_url":"https://api.github.com/repos/bendalab/thunderfish/forks","keys_url":"https://api.github.com/repos/bendalab/thunderfish/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bendalab/thunderfish/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bendalab/thunderfish/teams","hooks_url":"https://api.github.com/repos/bendalab/thunderfish/hooks","issue_events_url":"https://api.github.com/repos/bendalab/thunderfish/issues/events{/number}","events_url":"https://api.github.com/repos/bendalab/thunderfish/events","assignees_url":"https://api.github.com/repos/bendalab/thunderfish/assignees{/user}","branches_url":"https://api.github.com/repos/bendalab/thunderfish/branches{/branch}","tags_url":"https://api.github.com/repos/bendalab/thunderfish/tags","blobs_url":"https://api.github.com/repos/bendalab/thunderfish/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bendalab/thunderfish/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bendalab/thunderfish/git/refs{/sha}","trees_url":"https://api.github.com/repos/bendalab/thunderfish/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bendalab/thunderfish/statuses/{sha}","languages_url":"https://api.github.com/repos/bendalab/thunderfish/languages","stargazers_url":"https://api.github.com/repos/bendalab/thunderfish/stargazers","contributors_url":"https://api.github.com/repos/bendalab/thunderfish/contributors","subscribers_url":"https://api.github.com/repos/bendalab/thunderfish/subscribers","subscription_url":"https://api.github.com/repos/bendalab/thunderfish/subscription","commits_url":"https://api.github.com/repos/bendalab/thunderfish/commits{/sha}","git_commits_url":"https://api.github.com/repos/bendalab/thunderfish/git/commits{/sha}","comments_url":"https://api.github.com/repos/bendalab/thunderfish/comments{/number}","issue_comment_url":"https://api.github.com/repos/bendalab/thunderfish/issues/comments{/number}","contents_url":"https://api.github.com/repos/bendalab/thunderfish/contents/{+path}","compare_url":"https://api.github.com/repos/bendalab/thunderfish/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bendalab/thunderfish/merges","archive_url":"https://api.github.com/repos/bendalab/thunderfish/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bendalab/thunderfish/downloads","issues_url":"https://api.github.com/repos/bendalab/thunderfish/issues{/number}","pulls_url":"https://api.github.com/repos/bendalab/thunderfish/pulls{/number}","milestones_url":"https://api.github.com/repos/bendalab/thunderfish/milestones{/number}","notifications_url":"https://api.github.com/repos/bendalab/thunderfish/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bendalab/thunderfish/labels{/name}","releases_url":"https://api.github.com/repos/bendalab/thunderfish/releases{/id}","deployments_url":"https://api.github.com/repos/bendalab/thunderfish/deployments","created_at":"2016-01-25T10:22:55Z","updated_at":"2016-01-25T10:51:51Z","pushed_at":"2016-04-29T12:19:11Z","git_url":"git://github.com/bendalab/thunderfish.git","ssh_url":"git@github.com:bendalab/thunderfish.git","clone_url":"https://github.com/bendalab/thunderfish.git","svn_url":"https://github.com/bendalab/thunderfish","homepage":null,"size":364,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":11,"forks":5,"open_issues":11,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bendalab/thunderfish/pulls/24"},"html":{"href":"https://github.com/bendalab/thunderfish/pull/24"},"issue":{"href":"https://api.github.com/repos/bendalab/thunderfish/issues/24"},"comments":{"href":"https://api.github.com/repos/bendalab/thunderfish/issues/24/comments"},"review_comments":{"href":"https://api.github.com/repos/bendalab/thunderfish/pulls/24/comments"},"review_comment":{"href":"https://api.github.com/repos/bendalab/thunderfish/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bendalab/thunderfish/pulls/24/commits"},"statuses":{"href":"https://api.github.com/repos/bendalab/thunderfish/statuses/93fa1fff3863df3d57baf17fd2d2ee528323726b"}}}}