docs: def preprocessBams(bamFNs, seqFNPrefix, offsetFN, abtFN, areUniform, logger):
      '''
      This does the grunt work behind read extraction from a name-sorted BAM file.  If it isn't sorted, this will not work
      as intended.
      @param bamFNs - a list of '.bam' filenames for parsing
      @param seqFNPrefix - this is always of the form '<DIR>/seqs.npy'
      @param offsetFN - this is always of the form '<DIR>/offsets.npy'
      @param abtFN - this is always of the form '<DIR>/about.npy'
      @param areUniform - True if all sequences are of uniform length
      @param logger - logger object for output 
      '''
      #create a seqArray
      seqArray = []
      
      #prep to break this into several smaller sorted sequences
      tempFileId = 0
      seqsPerFile = 10000000
      maxSeqLen = -1
      numSeqs = 0
      
      subSortFNs = []
      
      for fnID, fn in enumerate(bamFNs):
          #open the file and read in starting form the second, every 4th line
          logger.info('Loading \''+fn+'\'...')
          
          bamFile = pysam.Samfile(fn, 'rb')
          i = 0
          
          nr = bamFile.next()
          constantSize = len(nr.seq)
          
          #go through each line
          while nr != None:
              #collect all reads that are the same as nr
              aligns = []
              nqname = nr.qname
              while nr != None and nr.qname == nqname:
                  aligns.append(nr)
                  try:
                      nr = bamFile.next()
                  except:
                      nr = None
              
              #reduce this to a simpler set
              reads = [None, None]
              for a in aligns:
                  if len(a.seq) != constantSize:
                      print 'DIFF SIZE='+str(len(a.seq))
                  
                  if a.flag & REVERSE_COMPLEMENTED_FLAG == 0:
                      #not reverse complemented
                      seq = a.seq
                  else:
                      seq = reverseComplement(a.seq)
                  
                  if a.flag & FIRST_SEGMENT_FLAG == 0:
                      #second segment
                      if reads[1] == None:
                          reads[1] = seq
                      elif reads[1] != seq:
                          logger.warning('Two sequences with same flag and different seqs: '+reads[1]+'\n'+str(a))
                  else:
                      if reads[0] == None:
                          reads[0] = seq
                      elif reads[0] != seq:
                          logger.warning('Two sequences with same flag and different seqs: '+reads[0]+'\n'+str(a))
              
              for j, r in enumerate(reads):
                  if r == None:
                      continue
                  
                  if r[1-j] == None:
                      seqArray.append((r+'$', fnID, i, 0xFF, 0xFFFFFFFFFFFFFFFF))
                  else:
                      seqArray.append((r+'$', fnID, i, fnID, i+1-2*j))
                  
                  if len(seqArray) == seqsPerFile:
                      if not areUniform or maxSeqLen == -1:
                          maxSeqLen = 0
                          for seq, fID, seqID, pfID, pseqID in seqArray:
                              if len(seq) > maxSeqLen:
                                  maxSeqLen = len(seq)
                      
                      tempFN = seqFNPrefix+'.sortTemp.'+str(tempFileId)+'.npy'
                      subSortFNs.append(tempFN)
                      
                      sys.stdout.write('\rWriting file '+str(tempFileId))
                      sys.stdout.flush()
                      tempArray = np.lib.format.open_memmap(tempFN, 'w+', 'a'+str(maxSeqLen)+',<u1,<u8,<u1,<u8', (len(seqArray),))
                      tempArray[:] = sorted(seqArray)
                      numSeqs += len(seqArray)
                      del tempArray
                      tempFileId += 1
                      seqArray = []
                  i += 1
                  
      sys.stdout.write('\n')
      if len(seqArray) > 0:
          if not areUniform or maxSeqLen == -1:
              maxSeqLen = 0
              for seq, fID, seqID, pfID, pseqID in seqArray:
                  if len(seq) > maxSeqLen:
                      maxSeqLen = len(seq)
          
          tempFN = seqFNPrefix+'.sortTemp.'+str(tempFileId)+'.npy'
          subSortFNs.append(tempFN)
          
          tempArray = np.lib.format.open_memmap(tempFN, 'w+', 'a'+str(maxSeqLen)+',<u1,<u8,<u1,<u8', (len(seqArray),))
          tempArray[:] = sorted(seqArray)
          numSeqs += len(seqArray)
          del tempArray
          tempFileId += 1
          seqArray = []
      
      logger.info('Pre-sorting '+str(numSeqs)+' sequences...')
      iters = []
      for fn in subSortFNs:
          iters.append(customiter(np.load(fn, 'r')))
      
      #save it
      tempFN = seqFNPrefix+'.temp.npy'
      fp = open(tempFN, 'w+')
      
      aboutFile = np.lib.format.open_memmap(abtFN, 'w+', '<u1,<u8,<u1,<u8', (numSeqs,))
      ind = 0
      
      for tup in heapq.merge(*iters):
          (seq, fID, seqID, pfID, pseqID) = tup
          aboutFile[ind] = (fID, seqID, pfID, pseqID)
          fp.write(seq)
          ind += 1
          
      fp.close()
      
      for fn in subSortFNs:
          os.remove(fn)
      
      #convert the sequences into uint8s and then save it
      del seqArray
      seqArray = np.memmap(tempFN)
      
      if areUniform:
          uniformLength = maxSeqLen
      else:
          uniformLength = 0
      
      logger.info('Saving sorted sequences for BWT construction...')
      MSBWTGen.writeSeqsToFiles(seqArray, seqFNPrefix, offsetFN, uniformLength)
      
      #wipe this
      del seqArray
      os.remove(tempFN)