docs: def iterateCreateFromSeqs(startingColumn, fmStarts, fmDeltas, allFirstCounts, allBwtCounts, cOffset, totalCounts, numValidChars,
                            mergedFN, seqFNPrefix, offsetFN, insertFNs, numProcs, areUniform, depth, logger):
      '''
      This function is the actual series of iterations that a BWT creation will perform.  It's separate so we can build a function
      for resuming construction if we fail for some reason.
      TODO: build a recovery function to start midway through BWT construction.
      TODO: @param values need explanation
      '''
      bwt = np.load(mergedFN, 'r+')
      
      column = startingColumn
      newInserts = True
      while newInserts:
          st = time.time()
          
          #iterate through the sorted keys
          keySort = sorted(fmStarts.keys())
          for i, key in enumerate(keySort):
              #all deltas get copied
              for c2 in xrange(0, numValidChars):
                  #copy only to the ones after key
                  allFirstCounts[int(key[0])] += fmDeltas[key][c2]
                  allBwtCounts[c2] += fmDeltas[key][c2]
                  for key2 in keySort[i+1:]:
                      fmStarts[key2][c2] += fmDeltas[key][c2]
                      
                      if key[0] == key2[0]:
                          cOffset[key2] += fmDeltas[key][c2]
                      
                  fmDeltas[key][c2] = 0
          
          #blank out the next insertions and make sure we set up the keys we already know about
          nextInsertFNs = {}
          for key in keySort:
              nextInsertFNs[key] = []
          
          #default to having no new insertions
          newInserts = False
          
          #generate tuples of data packets for processing
          tups = []
          for key in keySort:
              prevIterFN = mergedFN+'.'+key+'.'+str(column-1)+'.npy'
              cOff = cOffset[key]
              tup = (key, seqFNPrefix, offsetFN, mergedFN, prevIterFN, column, copy.deepcopy(fmStarts[key]), insertFNs[key], cOff, areUniform)
              tups.append(tup)
          
          if numProcs > 1:
              #TODO: chunksize?
              #create a pool of processes based on the input
              myPool = multiprocessing.Pool(numProcs)
              rets = myPool.imap(bwtPartialInsertPoolCall, tups, 1)
          else:
              rets = []
              for tup in tups:
                  rets.append(bwtPartialInsertPoolCall(tup))
          
          for i, ret in enumerate(rets):
              (retFmDelta, retInsertFNs, retShape) = ret
              key = keySort[i]
              
              for c in xrange(1, numValidChars):
                  if retInsertFNs[c] == None:
                      continue
                  
                  nextKey = (str(c)+key)[0:depth]
                  if not fmStarts.has_key(nextKey):
                      fmDeltas[nextKey] = [0]*numValidChars
                          
                      keyInd = bisect.bisect(keySort, nextKey)
                      if keyInd < len(keySort):
                          fmStarts[nextKey] = copy.deepcopy(fmStarts[keySort[keyInd]])
                      else:
                          fmStarts[nextKey] = copy.deepcopy(allBwtCounts)
                      
                      if keyInd == len(keySort) or keySort[keyInd][0] != nextKey[0]:
                          cOffset[nextKey] = allFirstCounts[int(nextKey[0])]
                      else:
                          cOffset[nextKey] = cOffset[keySort[keyInd]]
                      
                      np.lib.format.open_memmap(mergedFN+'.'+nextKey+'.'+str(column)+'.npy', 'w+', '<u8,<u1,<u4', (0,))
                  
                  for c2 in xrange(0, numValidChars):
                      fmDeltas[nextKey][c2] += retFmDelta[c][c2]
                  
                  if not nextInsertFNs.has_key(nextKey):
                      nextInsertFNs[nextKey] = []
                  
                  if retInsertFNs[c] != None:
                      nextInsertFNs[nextKey].append(retInsertFNs[c])
                      newInserts = True
              
              #None means we didn't change anything
              if retShape != None:
                  totalCounts[key] = retShape
          
          if numProcs > 1:
              myPool.terminate()
              myPool.join()
              myPool = None
          
          #at this point, we know everything is over, so we can clean up the previous step
          for key in keySort:
              prevIterFN = mergedFN+'.'+key+'.'+str(column-1)+'.npy'
              try:
                  os.remove(prevIterFN)
              except:
                  pass
              for fn in insertFNs[key]:
                  try:
                      os.remove(fn)
                  except:
                      pass
          
          insertFNs = nextInsertFNs
              
          #copy inserts and move to the next column
          column += 1
          
          et = time.time()
          logger.info('Finished iteration '+str(column-2)+' in '+str(et-st)+' seconds...')
              
      
      logger.info('Creating final output...')
      
      ei = 0
      sortedKeys = sorted(totalCounts.keys())
      for key in sortedKeys:
          copyArr = np.load(mergedFN+'.'+key+'.'+str(column-1)+'.npy', 'r')
          si = ei
          ei += totalCounts[key]
          bwt[si:ei] = copyArr[:]
          
      for key in sortedKeys:
          os.remove(mergedFN+'.'+key+'.'+str(column-1)+'.npy')