Exemple #1
0
def _demo_01_offests():
    """
    Demonstrate how to use sweepDataRange to estimate excellent offsets
    for pretty graphing of ABFs with wildly different scales.
    """
    for fname in sorted(glob.glob(PATH_DATA+"/*.abf"))[5:8]:
        abf = pyabf.ABF(fname)
        sweeps(abf, offsetXsec=abf.sweepLengthSec/20,
               offsetYunits=sweepDataRange(abf, .05))
        scalebar(abf)
    plt.show()
Exemple #2
0
def _demo_epoch_table():
    """Demonstrate the text epoch table feature."""
    import matplotlib.pyplot as plt
    abfFiles = glob.glob(PATH_DATA + "/18702001-*.abf")
    for fname in abfFiles:
        abf = pyabf.ABF(fname)
        print("\n\n", "#" * 20, abf.abfID, "(CH 1)", "#" * 20)

        # show the epoch table as a big text block
        epochTable = EpochTable(abf, 1)
        print(epochTable)
Exemple #3
0
    def demo_15_epochs(self):
        """
        ## Accessing Epoch Information

        In some ABFs an epoch table is used to control the command level of the
        DAC to control voltage or current. While the epoch table can be
        confusing to access directly from the header (e.g., the first epoch
        does not start at time 0, but rather 1/64 of the sweep length), a
        simplified way to access epoch types and levels is provided with the
        `abf.sweepEpochs` object, which contains epoch points, levels, and types
        for the currently-loaded sweep.

        For example, the output of this script:
        ```python
        import pyabf
        abf = pyabf.ABF("2018_08_23_0009.abf")
        for i, p1 in enumerate(abf.sweepEpochs.p1s):
            epochLevel = abf.sweepEpochs.levels[i]
            epochType = abf.sweepEpochs.types[i]
            print(f"epoch index {i}: at point {p1} there is a {epochType} to level {epochLevel}")
        ```

        looks like this:
        ```
        epoch index 0: at point 0 there is a Step to level -70.0
        epoch index 1: at point 187 there is a Step to level -80.0
        epoch index 2: at point 4187 there is a Step to level -70.0
        epoch index 3: at point 8187 there is a Ramp to level -80.0
        epoch index 4: at point 9187 there is a Ramp to level -70.0
        epoch index 5: at point 10187 there is a Step to level -70.0
        ```
        """

        import pyabf
        abf = pyabf.ABF("data/abfs/2018_08_23_0009.abf")

        fig = plt.figure(figsize=self.figsize)

        ax1 = fig.add_subplot(211)
        ax1.plot(abf.sweepY, color='b')
        ax1.set_ylabel("ADC (measurement)")
        ax1.set_xlabel("sweep point (index)")

        ax2 = fig.add_subplot(212)
        ax2.plot(abf.sweepC, color='r')
        ax2.set_ylabel("DAC (command)")
        ax2.set_xlabel("sweep point (index)")

        for p1 in abf.sweepEpochs.p1s:
            ax1.axvline(p1, color='k', ls='--', alpha=.5)
            ax2.axvline(p1, color='k', ls='--', alpha=.5)

        plt.tight_layout()
        self.saveAndClose()
Exemple #4
0
def test_findStimulusFile_NansIfNotFound():
    """When the stimulus file isn't found the waveform should be all NANs."""

    warnings.simplefilter("ignore")
    abf = pyabf.ABF(ABF_PATH)
    stimulus = abf.stimulusByChannel[0]
    waveform = stimulus.stimulusWaveform(stimulusSweep=0)

    assert isinstance(waveform, np.ndarray)
    assert len(waveform) == len(abf.sweepY)
    assert np.isnan(waveform).all()
Exemple #5
0
def _demo_sweepC():
    """Demonstrate how to generate the sweepC waveform."""
    import matplotlib.pyplot as plt
    for fname in glob.glob(PATH_DATA + "/18702001-*.abf"):
        abf = pyabf.ABF(fname)
        print("\n%s (CH 1)" % abf.abfID)
        epochTable = EpochTable(abf, 1)
        for sweep in abf.sweepList:
            sweepWaveform = epochTable.epochWaveformsBySweep[sweep]
            sweepC = sweepWaveform.getWaveform()
            print("SweepC", sweep, "=", sweepC)
Exemple #6
0
def getElectroPara(file):
    name = getCellID(file)
    abf = pyabf.ABF(file)
    rmp = abf.sweepY[abf.sweepEpochs.p1s[0]:abf.sweepEpochs.p2s[0]].mean()
    ivFile = AbfMatchIVfile(file)
    if ivFile:
        ivData = getOneIVdata(ivFile)
        RmRes = computeRm(ivData)
        return ({'ID': name, 'RMP': rmp, 'Rm': RmRes['Rm']})
    else:
        return None
Exemple #7
0
def getListOfProtocol(protocol="0111",
                      folderPath="X:/Data/SD/OXT-Subiculum/abfs"):
    matchingPaths = []
    for path in glob.glob(folderPath + "/*.abf"):
        abf = pyabf.ABF(path, loadData=False)
        if (abf.adcUnits[0] != "mV"):
            print("bad units: " + path)
            continue
        if abf.protocol.startswith("0111"):
            matchingPaths.append(path)
    return matchingPaths
def getIdealABFs():
    print("scanning ABFs...")
    idealAbfs = []
    for abfFilePath in glob.glob(PATH_DATA+"/*.abf"):
        abf = pyabf.ABF(abfFilePath)
        if (abf.sweepUnitsY == "pA"
                and abf.sweepLengthSec <= 60
                and abf.dataRate <= 20000):
            idealAbfs.append(abf)
    print(f"Found {len(idealAbfs)} ideal ABFs to analyze")
    return idealAbfs
Exemple #9
0
def getDataLine(abfFilePath):
    dataLine = ""
    try:
        abf = pyabf.ABF(abfFilePath, loadData=False)
        comments = " | ".join(abf.tagComments)
        abfPath = abfBrowse.getXdrivePath(abfFilePath)
        dataLine = f"ABF: {abfPath}, {abf.protocol}, {comments}"
        dataLine += "\n"
    except Exception as ex:
        print(f"### EXCEPTION: {ex}")
    return dataLine
def calc_refract_mean(list_of_files, sweep, channel=0):
    if not list_of_files:
        print(f"[calc_refract_mean] list_of_files is None, exiting")
    assert (len(list_of_files) == 5
            ), f"should be 5 files, but there are {len(list_of_files)}"
    b = []
    for f in list_of_files:
        abf = pyabf.ABF(f)
        abf.setSweep(sweep, channel=channel)
        b.append(abf.sweepY)
    b = np.asarray(b)
    return abf.sweepX, b.mean(axis=0)
def plot_stim_aligned(f_list,
                      stim_chan,
                      xii_chan,
                      dia_chan,
                      pre=0.1,
                      post=0.5):

    xii_slice = []
    dia_slice = []
    for f in f_list:
        dat = pyabf.ABF(f)
        sr = dat.dataRate
        pre_samp = int(pre * sr)
        post_samp = int(post * sr)
        tvec = np.arange(-pre, post, 1 / sr) * 1000

        stim_id = abf.get_channel_id_by_label(dat, stim_chan)
        xii_id = abf.get_channel_id_by_label(dat, xii_chan)
        dia_id = abf.get_channel_id_by_label(dat, dia_chan)

        for ii in range(dat.sweepCount):
            dat.setSweep(ii, stim_id)
            stim_on, stim_off = rlab_signal.binary_onsets(dat.sweepY, 1)
            stim_on = stim_on[0]
            stim_off = stim_off[0]
            dat.setSweep(ii, xii_id)
            xii_data = dat.sweepY
            xii_slice.append(xii_data[stim_on - pre_samp:stim_on + post_samp])

            dat.setSweep(ii, dia_id)
            dia_data = dat.sweepY
            dia_data = rlab_signal.remove_EKG(dia_data, sr)
            dia_data = rlab_signal.integrator(dia_data,
                                              sr,
                                              0.05,
                                              acausal=False)
            dia_slice.append(dia_data[stim_on - pre_samp:stim_on + post_samp])

    xii_slice = np.array(xii_slice).T
    dia_slice = np.array(dia_slice).T

    f, ax = plt.subplots(nrows=2, sharex=True, figsize=(3, 2))
    ax[0].plot(tvec, xii_slice, 'k', alpha=0.2, lw=1)
    ax[0].axvspan(0, (stim_off - stim_on) / sr * 1000, color='c', alpha=0.3)

    ax[1].plot(tvec, dia_slice, 'k', alpha=0.2, lw=1)
    ax[1].axvspan(0, (stim_off - stim_on) / sr * 1000, color='c', alpha=0.3)
    ax[1].set_xlabel('Time (ms)')

    ax[0].set_ylabel('XII')
    ax[1].set_ylabel('Dia')
    sns.despine()
    plt.tight_layout()
Exemple #12
0
def _demo_create_graphs():
    """Plot sweepC of ABFs containing waveforms of all types."""
    import matplotlib.pyplot as plt
    for fname in glob.glob(PATH_DATA + "/18702001-*.abf"):
        abf = pyabf.ABF(fname)
        plt.figure()
        eptbl = EpochTable(abf, 1)
        for epwv in eptbl.epochWaveformsBySweep:
            sweepC = epwv.getWaveform()
            plt.plot(sweepC)
        plt.title(abf.abfID)
    plt.show()
Exemple #13
0
def stimulusWaveformFromFile(abf, channel=0):
    """
    Attempt to find the stimulus file used to record an ABF, read the stimulus
    file (ABF or ATF), and return the stimulus waveform (as a numpy array).
    """

    assert isinstance(abf, pyabf.ABF)
    assert channel in abf.channelList

    # prepare potential file paths where the stimulus file may exist
    stimFname = abf._stringsIndexed.lDACFilePath[channel]
    stimBN = os.path.basename(stimFname)
    abfFolder = os.path.dirname(abf.abfFilePath)
    pathSameFolder = os.path.join(abfFolder, stimBN)
    pathAlt = os.path.join(str(abf.stimulusFileFolder), stimBN)

    # try to find the stimulus file
    if os.path.exists(stimFname):
        stimFname = os.path.abspath(stimFname)
    elif os.path.exists(pathSameFolder):
        stimFname = pathSameFolder
    elif pathAlt and os.path.exists(pathAlt):
        stimFname = pathAlt
    else:
        return np.full(abf.sweepPointCount, np.nan)

    # the stimulus waveform file was found, consider caching
    if abf._cacheStimulusFiles:
        stimFname = os.path.realpath(stimFname)
        if not stimFname in cachedStimuli.keys():
            if stimFname.upper().endswith(".ABF"):
                cachedStimuli[stimFname] = pyabf.ABF(stimFname)
            elif stimFname.upper().endswith(".ATF"):
                cachedStimuli[stimFname] = pyabf.ATF(stimFname)
        return cachedStimuli[stimFname].sweepY
    else:
        if stimFname.upper().endswith(".ABF"):
            return pyabf.ABF(stimFname)
        elif stimFname.upper().endswith(".ATF"):
            return pyabf.ATF(stimFname)
Exemple #14
0
def test_cookbook_createHeaderImages(abfPath):
    warnings.simplefilter("ignore")
    abf = pyabf.ABF(abfPath)
    assert isinstance(abf, pyabf.ABF)

    if platform.architecture()[0] == "32bit":
        raise Exception("ABF plotting with matplotlib requires 64-bit")

    # create figure and subplots
    fig = plt.figure(figsize=(8, 6))
    fig.patch.set_alpha(0)  # transparent background
    ax1 = fig.add_subplot(211)
    ax2 = fig.add_subplot(212)
    ax1.grid(alpha=.4, ls='--')
    ax2.grid(alpha=.4, ls='--')
    ax1.patch.set_facecolor('w')
    ax2.patch.set_facecolor('w')
    ax1.set_xmargin(0)
    ax2.set_xmargin(0)

    # overlap or continuous view depends on protocol
    absoluteTime = False
    if "0111" in abf.protocol:
        absoluteTime = True
    if "loose" in abf.protocol:
        absoluteTime = True

    # usually we plot channel 0, but sometimes manually override
    channel = 0
    if "18702001" in abf.abfID:
        channel = 1

    # plot the data sweep by sweep
    maxSweepsToPlot = min(abf.sweepCount, 20)
    for sweep in range(maxSweepsToPlot):
        abf.setSweep(sweep, channel=channel, absoluteTime=absoluteTime)
        ax1.plot(abf.sweepX, abf.sweepY, alpha=.5, color='b', lw=.5)
        ax2.plot(abf.sweepX, abf.sweepC, color='r')

    # decorate plot and save it
    ax1.set_title(
        f"{abf.abfID}.abf [channel: {abf.sweepChannel+1}/{abf.channelCount}] [sweeps: {abf.sweepNumber+1}]"
    )
    ax1.set_ylabel(abf.sweepLabelY)
    ax1.set_xlabel(abf.sweepLabelX)
    ax2.set_ylabel(abf.sweepLabelC)
    ax2.set_xlabel(abf.sweepLabelX)
    fig.tight_layout()
    ax1.margins(0, .1)
    ax2.margins(0, .1)
    fig.savefig(f"{PATH_HEADERS}/{abf.abfID}.png")
    plt.close()
Exemple #15
0
def pageParentChildAbfList(abfFolder, parentNote):
    assert isinstance(abfFolder, abfBrowse.AbfFolder)
    assert isinstance(parentNote, abfBrowse.cellsFile.CellNote)
    abfs = abfFolder.abfList.family[parentNote.abfID]
    abfFileNames = [x+".abf" for x in abfs]
    abfPaths = [os.path.join(abfFolder.path, x) for x in abfFileNames]

    html = ""
    html += "<div style='background-color: #EEE; padding: .5em;'>"
    for i, abfFileName in enumerate(abfFileNames):

        # don't list ABFs currently being recorded
        rsvFilePath = os.path.splitext(abfPaths[i])[0]+".rsv"
        if os.path.exists(rsvFilePath):
            continue

        # use pyABF to extract useful ABF information
        abf = pyabf.ABF(abfPaths[i], loadData=False)
        clampType = "VC" if abf.adcUnits[0] == "pA" else "IC"
        sweepCount = len(abf.sweepList)
        duration = f"{round(abf.dataLengthMin, 2)} min" if abf.dataLengthMin > 1 else f"{round(abf.dataLengthSec, 2)} sec"
        comments = []
        for tagComment, tagTimeMin in zip(abf.tagComments, abf.tagTimesMin):
            comments.append("\"%s\" at %s min" %
                            (tagComment, round(tagTimeMin, 2)))
        commentsLine = ", ".join(comments)

        # determine abf type by its protocol
        isMemTest = ("memtest" in abf.protocol.lower()
                     or "membrane" in abf.protocol.lower())

        # create the HTML row for this ABF
        html += f"<div class='abfInfoRow'>{abfFileName} "
        xDrivePath = abfBrowse.getXdrivePath(abfPaths[i])
        html += abfBrowse.htmlTools.copyButton("copy path", xDrivePath)
        setpathCommand = "setpath \"%s\"; " % (xDrivePath)
        html += abfBrowse.htmlTools.copyButton("setpath", setpathCommand)
        html += abfBrowse.htmlTools.ignoreButton(abfPaths[i])
        html += f"{abf.protocol}, {clampType} with {sweepCount} sweeps ({abf.sweepLengthSec} sec each, {duration} total)"

        # display messages at the end of the line
        if (len(comments)):
            html += f", <span class='abfInfoComment'>Comments: {commentsLine}</span>"
        if i == 0 and not isMemTest:
            html += f" <span class='abfInfoWarning'>WARNING: the parent ABF should be a memtest!</span>"
        if (abf.adcUnits[0] == abf.dacUnits[0]):
            html += f" <span class='abfInfoWarning'>WARNING: unit error!</span>"

        html += "</div>"

    html += "</div>"
    return html
def test_stimulus_cache(useCache=True):
    """Load ABFs which use an external ABF and ATF stimulus files"""
    abfFiles = sorted(glob.glob(testDirectory + "/cool_*.abf"))
    for i, filename in enumerate(abfFiles):
        #abf = pyabf.ABF(filename, cacheStimulusFiles=False)
        abf = pyabf.ABF(filename)
        abf.stimulusFileFolder = PATH_DATA  # alternate path for stimulus files
        t1 = time.perf_counter()
        sweepC = abf.sweepC  # stimulus file is only read if this is accessed
        t2 = time.perf_counter()
        stimFile = os.path.basename(abf._stringsIndexed.lDACFilePath[0])
        timeMs = (t2 - t1) * 1000.0
        print('"%s" loaded in %.02f ms' % (stimFile, timeMs), sweepC)
Exemple #17
0
    def demo_02a_plot_matplotlib_sweep(self):
        """
        ## Plot Sweep Data

        Plot a sweep of ABF data using matplotlib.
        """

        import pyabf
        abf = pyabf.ABF("data/abfs/17o05028_ic_steps.abf")
        abf.setSweep(14)
        plt.figure(figsize=self.figsize)
        plt.plot(abf.sweepX, abf.sweepY, lw=.5)
        self.saveAndClose()
Exemple #18
0
def addFakeParentImages(abfFolder,
                        parentProtocols=['0201 memtest', '1 MTIV3']):
    tifSourcePath = R"X:\Users_Public\Scott\x.tif"
    for abfPath in glob.glob(abfFolder + "/*.abf"):
        abf = pyabf.ABF(abfPath, loadData=False)
        for protocol in parentProtocols:
            if protocol in abf.protocol:
                abfFileName = os.path.basename(abfPath)
                tifFileName = os.path.basename(abfPath.replace(".abf", ".tif"))
                tifFilePath = os.path.join(abfFolder, tifFileName)
                if not os.path.exists(tifFilePath):
                    print("CREATING:", tifFilePath)
                    shutil.copy(tifSourcePath, tifFilePath)
Exemple #19
0
    def __init__(self,
                 sweep_info=None,
                 abf_file=None,
                 ontology=None,
                 api_sweeps=True,
                 validate_stim=True):
        super(ABFDataSet, self).__init__(ontology, validate_stim)
        self._abf_data = pyabf.ABF(abf_file)

        if sweep_info is None:
            sweep_info = self.extract_sweep_stim_info()

        self.build_sweep_table(sweep_info)
def load_abf(fpath=fpath):
    print('Loading %s' % fpath)

    a = pyabf.ABF(fpath)
    fs = a.dataRate # sampling frequency
    V = a.data
    t = np.arange(0, len(V[0])) * (1.0 / fs) # length of the data, converted to seconds by dividing by the sampling frequency
    print('ABF File Comment: ', a.abfFileComment)
    print('Sampling rate: ', fs)
    print('length of recording (seconds): ', t[-1])
    print('number of datapoints: ', len(V[0]))

    return a, fs, t, V
Exemple #21
0
def process_files( files ):
    global args_
    if args_.dir:
        resdir = os.path.join(args_.dir, '_CSV')
        if not os.path.isdir(resdir):
            os.makedirs(resdir)
    else:
        resdir = os.path.dirname(args_.input)

    for f in files:
        abf = pyabf.ABF( f )
        df = extractData(abf)
        saveData(df, os.path.join(resdir
            , '%s.csv' % relative_path(f, args_.dir)))
Exemple #22
0
def go():
    print("Testing core API", end=" ")

    abf1 = pyabf.ABF(PATH_DATA+"/05210017_vc_abf1.abf")
    abf2 = pyabf.ABF(PATH_DATA+"/18702001-ramp.abf")

    log.debug("Testing generic calls which work on any ABF")

    for functionName in sorted(globals()):
        if not functionName.startswith("test_"):
            continue

        log.debug(f"Running {functionName}() on {abf1.abfID} (ABF1)")
        globals()[functionName](abf1)

        log.debug(f"Running {functionName}() on {abf2.abfID} (ABF2)")
        globals()[functionName](abf2)

    log.debug("Testing calls work best on specific ABFs")
    specialTest_comments(PATH_DATA+"/16d05007_vc_tags.abf",commentCount=2)
    specialTest_comments(PATH_DATA+"/abf1_with_tags.abf",commentCount=1)
    generateMarkdown()
    print(" OK")
    def __init__(self,
                 file_path: str,
                 sampling_rate: int = None,
                 trace_threshold: float = 0,
                 rate_threshold: float = 5):
        self.file_path = file_path
        self.sampling_rate = sampling_rate
        self.trace_threshold = trace_threshold
        self.rate_threshold = rate_threshold

        # Read abf file
        self.abf = pyabf.ABF(file_path)
        self.sweep_list = self.abf.sweepList
        self.sweep_count = len(self.sweep_list)
Exemple #24
0
def good_path_and_map():
    path = str(pathlib.Path("data", "abfs", "20104002.abf").resolve())
    abf = pyabf.ABF(path)
    abf.setSweep(sweepNumber=1, channel=0)
    good = {
        "path": path,
        "sweep": 1,
        "channel": 0,
        "x": abf.sweepX,
        "y": abf.sweepY,
        "short_name": "20104002",
        "error": [],
    }
    return path, good
Exemple #25
0
 def get_current_step(self, file_id=0, file=""):
     """Returns the current step of the n-th abf file."""
     if not (file):
         file = self.files["abf"][file_id]
         check = self.check_abf_valid(file_id)
     else:
         check = self.check_abf_valid(file=file)
     apDemoAbf = pyabf.ABF(file)
     cur_step = []
     if check:
         for sweep in apDemoAbf.sweepList:
             apDemoAbf.setSweep(sweep)
             cur_step.append(apDemoAbf.sweepEpochs.levels[2])
     return cur_step
Exemple #26
0
def autoAnalyzeAbf(abf, reanalyze=True):
    """
    Given an abf filename (or ABF object), produce an analysis graph of its
    data. If the protocol has a known analysis routine, run it. If not, run
    the unknown() analysis routine. In all cases, an input ABF should produce
    at least some type of output graph.
    """

    # error checking
    if isinstance(abf, str):
        abf = pyabf.ABF(abf, False)
    assert isinstance(abf, pyabf.ABF)
    log.debug(f"Auto-analyzing {abf.abfID}.abf")

    # determine if old files exist
    matchingFiles = abfnav.dataFilesForAbf(abf.abfFilePath)
    if reanalyze is False:
        if len(matchingFiles):
            log.debug(f"skipping {abf.abfID} (data files exist)")
            return
    else:
        for fname in matchingFiles:
            if ".tif" in fname.lower():
                continue
            log.debug(f"deleting {fname}")
            os.remove(fname)

    # if the protocol is in the autoanalysis format determine its function
    functionName = None
    if " " in abf.protocol and len(abf.protocol.split(" ")[0]) == 4:
        functionName = "protocol_"+abf.protocol.split(" ")[0]
        if not functionName in dir(analysisByProtocol):
            functionName = None
        if functionName and not hasattr(analysisByProtocol, functionName):
            functionName = None

    # if a properly formatted protoocl was found, run its analysis
    if functionName:
        log.debug(f"analyzing known protocol via: {functionName}()")
        getattr(analysisByProtocol, functionName)(abf)
    else:
        msg = f"{abf.abfID} uses an unknown protocol: {abf.protocol}"
        log.warn(msg)
        with open(os.path.dirname(abf.abfFilePath)+"/pyabf.log", 'a') as f:
            timestamp = str(datetime.datetime.now())
            f.write(f"[{timestamp}] [{abf.abfFilePath}] {msg}\n")
        log.debug("analyzing with unknown()")
        analysisByProtocol.unknown(abf)
    return
 def thefile(self, dropdownfile):
     self.fullfilepath = os.path.join(self.fileloc, dropdownfile)
     self.currentfile = dropdownfile
     self.abf = pyabf.ABF(self.fullfilepath)
     self.numsweep = self.abf.sweepCount - 1
     self.slidsweep = interact(
         self.setsweep,
         sweeppick=widgets.IntSlider(
             min=0,
             max=self.numsweep,
             values=1,
             step=1,
             description='Sweep:',
         ),
     )
def test_cookbook_createHeaderPages(abfPath):
    abf = pyabf.ABF(abfPath)
    assert isinstance(abf, pyabf.ABF)
    page = abfInfoPage(abf)

    # modify a few infos to make things cleaner for source control
    abfFilePath = f"C:/some/path/to/{abf.abfID}.abf"
    abfFolderPath = f"C:/some/path"
    page.replaceThing("abfFilePath", abfFilePath)
    page.replaceThing("stimulusFileFolder", abfFilePath)
    page.replaceThing("abfFolderPath", abfFolderPath)
    page.replaceThing("strings", "not shown due to non-ASCII characters")

    with open(f"{PATH_HEADERS}/{abf.abfID}.md", 'w') as f:
        f.write(page.generateMarkdown())
def return_flat_list_of_treatment(dict_of_groups, treatment):
    try:
        abf = pyabf.ABF(dict_of_groups[0]["fpath"])
        time = abf.sweepX
    except TypeError as e:
        print(f"ERROR! \n {dict_of_groups}\n")
    target = [
        db.str_list_to_list_ints(peaks["peaks"])
        for peaks in dict_of_groups
        if peaks["treatment"] == treatment
    ]
    empty_less = [i for i in target if i]
    flat = [item for sublist in empty_less for item in sublist]
    x_time = time[flat]
    return x_time, flat
def figure_quietVsNoisy():

    plt.figure(figsize=(8, 6))

    plt.subplot(211)
    abf = pyabf.ABF(PATH_DATA+"/171116sh_0011.abf")  # noisy
    plt.title(f"171116sh_0011.abf (RMS noise: 1.769  pA)")
    plt.ylabel(abf.sweepLabelY)
    plt.plot(abf.sweepX, abf.sweepY, alpha=.3)
    plt.plot(abf.sweepX, lowPassHanning(abf, 1), color='k', lw=1)
    plt.axis([.30, .50, -225, -100])

    plt.subplot(212)
    abf = pyabf.ABF(PATH_DATA+"/f1_saved.abf")  # noisy
    plt.title(f"f1_saved.abf (RMS noise: 4.933 pA)")
    plt.plot(abf.sweepX, abf.sweepY, alpha=.3)
    plt.plot(abf.sweepX, lowPassHanning(abf, 1), color='k', lw=1)
    plt.ylabel(abf.sweepLabelY)
    plt.xlabel(abf.sweepLabelX)
    plt.axis([.68, .88, -125, 0])

    plt.tight_layout()
    plt.savefig("2019-06-07 auto detect lowpass filter 4.png")
    plt.show()