docs: def fileMD5(filename, partial=True):
      '''Calculate partial MD5, basically the first and last 8M
      of the file for large files. This should signicicantly reduce
      the time spent on the creation and comparison of file signature
      when dealing with large bioinformat ics datasets. '''
      filesize = os.path.getsize(filename)
      # calculate md5 for specified file
      md5 = hash_md5()
      block_size = 2**20  # buffer of 1M
      try:
          # 2**24 = 16M
          if (not partial) or filesize < 2**24:
              with open(filename, 'rb') as f:
                  while True:
                      data = f.read(block_size)
                      if not data:
                          break
                      md5.update(data)
          else:
              count = 16
              # otherwise, use the first and last 8M
              with open(filename, 'rb') as f:
                  while True:
                      data = f.read(block_size)
                      count -= 1
                      if count == 8:
                          # 2**23 = 8M
                          f.seek(-2**23, 2)
                      if not data or count == 0:
                          break
                      md5.update(data)
      except IOError as e:
          sys.exit(f'Failed to read {filename}: {e}')
      return md5.hexdigest()