def LoadGroupedZCroppedByTxtInput(dirname, StartStopTxt, mergeOperation=None):
    """StartStopTxt gives the range to load for each stack... "0: 4-9\n1: 5-10\n2: 5-11"
    The stack number before the colon is NOT ACTUALLY USED, stacks are just processed in order.
    For mergeOperation, select 'None','mean','max','min',or 'sum'"""
    StartStop = [map(int, i.replace(" ", "").split(":")[1].split("-")) for i in StartStopTxt.split("\n")]
    stacks = []
    for i, p in enumerate(StartStop):
        stacks.append([])
        files = getSortedListOfFiles(dirname, globArg="*_" + str(i) + "_*PMT1.TIF")
        files = files[p[0] : p[1] + 1]  # only pick out some files
        for f in files:
            stacks[-1].append(LoadSingle(f))
        stacks[-1] = np.array(stacks[-1])

    if mergeOperation in ["mean", "max", "min", "sum"]:
        return np.array([i.__getattribute__(mergeOperation)(axis=0) for i in stacks])
    elif mergeOperation != None:
        print "Invalid mergeOperation!  Returning the stacks list instead"

    return stacks  # has to be a list not an array b/c elements might not be the same length
def GetDirectoryFiles(dirname=None, wildcard='*[!.txt]'):
    dirname = _select_dir_if_none(dirname)
    return getSortedListOfFiles(dirname, globArg=wildcard)