This is a single process call of a chunk of the data to merge BWTs
    @param bID - the block ID this process is processing
    @param binSize - the size of a bin/block
    @param vcLen - 6, hardcoded upstream
    @param currOffsetCounts - the starting position in each input BWT for this process chunk, useful for FM extraction
    @param placeArrayFN - the filename for the input origin bits
    @param nextPlaceArrayFN - the filename for the output origin bits
    @param bwtDirs - the actual input BWT directories to merge

def mergeNewMSBWTPoolCall(tup):
    '''
    This is a single process call of a chunk of the data to merge BWTs
    @param bID - the block ID this process is processing
    @param binSize - the size of a bin/block
    @param vcLen - 6, hardcoded upstream
    @param currOffsetCounts - the starting position in each input BWT for this process chunk, useful for FM extraction
    @param placeArrayFN - the filename for the input origin bits
    @param nextPlaceArrayFN - the filename for the output origin bits
    @param bwtDirs - the actual input BWT directories to merge
    '''
    (bID, binSize, vcLen, currOffsetCounts, placeArrayFN, nextPlaceArrayFN, bwtDirs) = tup
    
    #load things to run
    placeArray = np.load(placeArrayFN, 'r')
    nextPlaceArray = np.load(nextPlaceArrayFN, 'r+')
    
    numInputs = len(bwtDirs)
    msbwts = [None]*numInputs
    mergedLength = 0
    for i, bwtDir in enumerate(bwtDirs):
        msbwts[i] = MultiStringBWT.loadBWT(bwtDir)
        mergedLength += msbwts[i].totalSize
        
    #state info we need to pass back
    nextBinHasChanged = {}
    nextOffsetCounts = {}
    needsMoreIterations = False
    
    #get the region and count the number of 0s, 1s, 2s, etc.
    region = placeArray[bID*binSize:(bID+1)*binSize]
    srcCounts = np.bincount(region, minlength=numInputs)
    
    #first extract the two subregions from each bwt
    inputIndices = currOffsetCounts
    chunks = [None]*numInputs
    for x in xrange(0, numInputs):
        chunks[x] = msbwts[x].getBWTRange(int(inputIndices[x]), int(inputIndices[x]+srcCounts[x]))
        
    #count the number of characters of each
    bcs = [None]*numInputs
    for x in xrange(0, numInputs):
        bcs[x] = np.bincount(chunks[x], minlength=vcLen)
    
    #interleave these character based on the region
    cArray = np.zeros(dtype='<u1', shape=(region.shape[0],))
    for x in xrange(0, numInputs):
        cArray[region == x] = chunks[x]
    
    #calculate curr using the MSBWT searches
    curr = np.zeros(dtype='<u8', shape=(vcLen,))
    for x in xrange(0, numInputs):
        curr += msbwts[x].getFullFMAtIndex(int(inputIndices[x]))
    
    #this is the equivalent of bin sorting just this small chunk
    for c in xrange(0, vcLen):
        totalC = 0
        for x in xrange(0, numInputs):
            totalC += bcs[x][c]
        
        if totalC == 0:
            continue
        
        #extract the zeroes and ones for this character
        packed = region[cArray == c]
        
        #calculate which bin they are in and mark those bins are changed if different
        b1 = int(math.floor(curr[c]/binSize))
        b2 = int(math.floor((curr[c]+totalC)/binSize))
        if b1 == b2:
            if not np.array_equal(placeArray[curr[c]:curr[c]+packed.shape[0]], packed):
                nextBinHasChanged[b1] = True
                needsMoreIterations = True
            
            origins = np.bincount(packed, minlength=numInputs)
            nextOffsetCounts[b1] = origins+nextOffsetCounts.get(b1, (0,)*numInputs)
            
        else:
            #b1 and b2 are different bins
            delta = b2*binSize-curr[c]
            if not np.array_equal(placeArray[curr[c]:b2*binSize], packed[0:delta]):
                nextBinHasChanged[b1] = True
                needsMoreIterations = True
            
            if not np.array_equal(placeArray[b2*binSize:b2*binSize+packed.shape[0]-delta], packed[delta:]):
                nextBinHasChanged[b2] = True
                needsMoreIterations = True
            
            origins1 = np.bincount(packed[0:delta], minlength=numInputs)
            nextOffsetCounts[b1] = origins1+nextOffsetCounts.get(b1, (0,)*numInputs)
            
            origins2 = np.bincount(packed[delta:], minlength=numInputs)
            nextOffsetCounts[b2] = origins2+nextOffsetCounts.get(b2, (0,)*numInputs)
            
        #this is where we actually do the updating
        nextPlaceArray[curr[c]:curr[c]+totalC] = packed[:]
        
    #cleanup time
    del srcCounts
    del region
    del chunks
    del cArray
    gc.collect()
    
    return (bID, nextBinHasChanged, nextOffsetCounts, needsMoreIterations)