code: def get_equivalent_positions(block):
      consensus = block['sequences'][0]['seq']
      rest = block['sequences'][1:]
      if '-' in consensus or '.' in consensus:
          raise ValueError("First sequence (consensus?) contains gaps")
      seen = set()
      dupes = set()
      for rec in rest:
          if rec['id'] in seen:
              dupes.add(rec['id'])
          else:
              seen.add(rec['id'])
      if dupes:
          raise ValueError("Duplicate sequences:\n" + '\n'.join(dupes))
      curr_shift = {}
      curr_resn = {}
      for rec in rest:
          curr_shift[rec['id']] = 0
          curr_resn[rec['id']] = rec['head_len']
      equivalencies = dict((i+1, {}) for i in xrange(len(consensus)))
      for i, char in enumerate(consensus):
          assert char.isupper()
          for rec in rest:
              rid = rec['id']
              strposn = i + curr_shift[rid]
              if rec['seq'][strposn].isupper():
                  curr_resn[rid] += 1
              elif rec['seq'][strposn].islower():
                  while rec['seq'][strposn].islower():
                      curr_shift[rid] += 1
                      curr_resn[rid] += 1
                      strposn += 1
                  curr_resn[rid] += 1
              else:
                  assert rec['seq'][strposn] in '.-'
                  continue
              equivalencies[i+1][rid] = curr_resn[rid]
      return equivalencies