Next / Previous / Contents / TCC Help System / NM Tech homepage

10.19. hist.cgi: lumpCompoundForm

Most compound forms (hybrids and species pairs) will not be affected if the user selects subspecies lumping. However, there are a few cases that are. For example, Dr. John Trochet, compiler of the Zuñi CBC, often reports hybrids of different forms of Dark-eyed Junco. Also, a record reported as “Audubon or Myrtle Warbler” should be report as Yellow-rumped Warbler if the user has requested subspecies lumping.

# - - -   l u m p C o m p o u n d F o r m

def lumpCompoundForm(c, txny):
    '''Subspecies lumping: compound form case

      [ (c is a pycbc.Census instance with a compound form) and
        (txny is a taxonomy as an xnomo3.Txny instance) ->
          if c.form and c.alt_form are defined in txny ->
            if c.form and c.alt_form are subspecies of
            the same species ->
              return the code for that species
            else -> return None
          else -> raise ScriptError ]

In order to check the ranks of the affected taxa, we retrieve the depth codes for subspecies and species ranks.

    #-- 1
    # [ subspDepth  :=  depth of subspecies rank in txny
    #   spDepth  :=  depth of species rank in txny ]
    subspDepth = txny.hier.formRank().depth
    spDepth = txny.hier.speciesRank().depth

The first step is to retrieve the Taxon instances for both the component form codes, assuming that they are known to the taxonomic database.

    #-- 2
    # [ if c.form and c.alt_form are defined in txny ->
    #     taxon1  :=  the txny.Taxon instance for c.form
    #     taxon2  :=  the txny.Taxon instance for c.alt_form
    #   else -> raise ScriptError ]
        taxon1 = txny.lookupAbbr(c.form)
    except KeyError:
        raise lib.ScriptError("Unknown bird code in %s-%s: '%s'" %
            (c.year_no, c.year_key, c.form))

        taxon2 = txny.lookupAbbr(c.alt_form)
    except KeyError:
        raise lib.ScriptError("Unknown bird code in %s-%s: '%s'" %
            (c.year_no, c.year_key, c.alt_form))

If either of these taxa are not subspecies, return None to signify that there is no change.

    #-- 3
    # [ if taxon1 and taxon2 are both subspecies ->
    #     I
    #   else -> return None ]
    if ((taxon1.rank.depth != subspDepth) or
        (taxon2.rank.depth != subspDepth)):
       return None

At this point we know that both form codes are subspecies, but they might be subspecies of different species. Fortunately, the xnomo3 module's Taxon class has a handy method that computes the deepest common ancestor of two taxa; if this ancestor is at species level, we can conclude that taxon1 and taxon2 are subspecies of that same species.

    #-- 4
    # [ if the nearest common ancestor of taxon1 and taxon2 has
    #   species rank ->
    #     return the code for that ancestor
    #   else -> return None ]
    commonAncestor = taxon1.nearestAncestor(taxon2)
    if commonAncestor.rank.depth == spDepth:
        return commonAncestor.abbr
        return None