docs: def global_alignment(query, target=None, targets=None, match=3, mismatch=-2, gap_open=-5, gap_extend=-2,
          score_match=None, score_mismatch=None, score_gap_open=None,
          score_gap_extend=None, matrix=None, aa=False):
      '''
      Needleman-Wunch global pairwise alignment.
  
      With ``global_alignment``, you can score an alignment using different
      paramaters than were used to compute the alignment. This allows you to
      compute pure identity scores (match=1, mismatch=0) on pairs of sequences
      for which those alignment parameters would be unsuitable. For example::
  
          seq1 = 'ATGCAGC'
          seq2 = 'ATCAAGC'
  
      using identity scoring params (match=1, all penalties are 0) for both alignment
      and scoring produces the following alignment::
  
          ATGCA-GC
          || || ||
          AT-CAAGC
  
      with an alignment score of 6 and an alignment length of 8 (identity = 75%). But
      what if we want to calculate the identity of a gapless alignment? Using::
  
          global_alignment(seq1, seq2,
                           gap_open=20,
                           score_match=1,
                           score_mismatch=0,
                           score_gap_open=10,
                           score_gap_extend=1)
  
      we get the following alignment::
  
          ATGCAGC
          ||  |||
          ATCAAGC
  
      which has an score of 5 and an alignment length of 7 (identity = 71%). Obviously,
      this is an overly simple example (it would be much easier to force gapless alignment
      by just iterating over each sequence and counting the matches), but there are several
      real-life cases in which different alignment and scoring paramaters are desirable.
  
      Args:
  
          query: Query sequence. ``query`` can be one of four things:
  
              1. a nucleotide or amino acid sequence, as a string
  
              2. a Biopython ``SeqRecord`` object
  
              3. an AbTools ``Sequence`` object
  
              4. a list/tuple of the format ``[seq_id, sequence]``
  
          target: A single target sequence. ``target`` can be anything that
              ``query`` accepts.
  
          targets (list): A list of target sequences, to be proccssed iteratively.
              Each element in the ``targets`` list can be anything accepted by
              ``query``.
  
          match (int): Match score for alignment. Should be a positive integer. Default is 3.
  
          mismatch (int): Mismatch score for alignment. Should be a negative integer. Default is -2.
  
          gap_open (int): Penalty for opening gaps in alignment. Should be a negative integer.
              Default is -5.
  
          gap_extend (int): Penalty for extending gaps in alignment. Should be a negative
              integer. Default is -2.
  
          score_match (int): Match score for scoring the alignment. Should be a positive integer.
              Default is to use the score from ``match`` or ``matrix``, whichever is provided.
  
          score_mismatch (int): Mismatch score for scoring the alignment. Should be a negative
              integer. Default is to use the score from ``mismatch`` or ``matrix``, whichever
              is provided.
  
          score_gap_open (int): Gap open penalty for scoring the alignment. Should be a negative
              integer. Default is to use ``gap_open``.
  
          score_gap_extend (int): Gap extend penalty for scoring the alignment. Should be a negative
              integer. Default is to use ``gap_extend``.
  
          matrix (str, dict): Alignment scoring matrix. Two options for passing the alignment matrix:
  
              - The name of a built-in matrix. Current options are ``blosum62`` and ``pam250``.
  
              - A nested dictionary, giving an alignment score for each residue pair. Should be
                formatted such that retrieving the alignment score for A and G is accomplished by::
  
                  matrix['A']['G']
  
          aa (bool): Must be set to ``True`` if aligning amino acid sequences. Default
              is ``False``.
  
      Returns:
  
          If a single target sequence is provided (via ``target``), a single ``NWAlignment``
          object will be returned. If multiple target sequences are supplied (via ``targets``),
          a list of ``NWAlignment`` objects will be returned.
      '''
      if not target and not targets:
          err = 'ERROR: You must supply a target sequence (or sequences).'
          raise RuntimeError(err)
      if target:
          targets = [target, ]
      if type(targets) not in (list, tuple):
          err = 'ERROR: ::targets:: requires an iterable (list or tuple).'
          err += 'For a single sequence, use ::target::'
          raise RuntimeError(err)
      alignments = []
      for t in targets:
          alignment = NWAlignment(query=query,
                                  target=t,
                                  match=match,
                                  mismatch=mismatch,
                                  gap_open=gap_open,
                                  gap_extend=gap_extend,
                                  score_match=score_match,
                                  score_mismatch=score_mismatch,
                                  score_gap_open=score_gap_open,
                                  score_gap_extend=score_gap_extend,
                                  matrix=matrix,
                                  aa=aa)
          alignments.append(alignment)
      if target is not None:
          return alignments[0]
      return alignments