docs: def preprocessFastqs(fastqFNs, seqFNPrefix, offsetFN, abtFN, areUniform, logger):
      '''
      This function does the grunt work behind string extraction for fastq files
      @param fastqFNs - a list of .fq 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 = []
      
      tempFileId = 0
      seqsPerFile = 1000000
      maxSeqLen = -1
      numSeqs = 0
      
      subSortFNs = []
      
      for fnID, fn in enumerate(fastqFNs):
          #open the file and read in starting form the second, every 4th line
          logger.info('Loading \''+fn+'\'...')
          if fn.endswith('.gz'):
              fp = gzip.open(fn, 'r')
          else:
              fp = open(fn, 'r')
          i = -1
          
          #go through each line
          for line in fp:
              if i % 4 == 0:
                  seqArray.append((line.strip('\n')+'$', fnID, i/4))
                  if len(seqArray) == seqsPerFile:
                      if not areUniform or maxSeqLen == -1:
                          maxSeqLen = 0
                          for seq, fID, seqID 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', (len(seqArray),))
                      tempArray[:] = sorted(seqArray)
                      numSeqs += len(seqArray)
                      del tempArray
                      tempFileId += 1
                      seqArray = []
              i += 1
                  
          fp.close()
      
      if len(seqArray) > 0:
          if not areUniform or maxSeqLen == -1:
              maxSeqLen = 0
              for seq, fID, seqID 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', (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', (numSeqs,))
      ind = 0
      
      for tup in heapq.merge(*iters):
          (seq, fID, seqID) = tup
          aboutFile[ind] = (fID, seqID)
          fp.write(seq)
          ind += 1
          
      fp.close()
      
      #clean up disk space
      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)