This function build and returns a function that implements
an alias set (see Section 3.1, “Alias sets”) as a
census-filter (see Section 14.1, “census-filter” for the definition of
this interface).
A census-filter, in general, takes as an argument
a pycbc.Census instance and returns an instance
of the same class, either the original or a new one.
To implement an alias set, this function requires two dictionaries as arguments:
Each entry in the singles dictionary list is
a tuple (, where this alias
set is to replace all occurrences of old,
new) with old.
new
For example, for a given alias set to replace all references
to Boat-tailed Grackle records with Great-tailed Grackle,
the singles argument would include the tuple
('BOTGRA', 'GRTGRA').
Each entry in the triples dictionary list is
a tuple (, where this alias set is to replace all
occurrences of the compound form oldForm,
rel, oldAlt, newForm) by the simple
form oldForm+rel+altForm.
newForm
For example, for an alias set to replace references to the
compound form Boat-tailed Grackle/Great-tailed Grackle with
the simple form Great-tailed Grackle, the triples argument would include the tuple ('BOTGRA', '/', 'GRTGRA', 'GRTGRA'). Note that in
the CBC database, species pairs and hybrids must insure
that the form field must be less than the
alt_form field, so it will never contain a
census record for 'GRTGRA/BOTGRA'.
# - - - a l i a s F a c t o r y
def aliasFactory(singles=None, triples=None):
'''Return a census-filter that implements an alias set.
[ (singles is a sequence of (oldForm, newForm) tuples defining
cases where (oldForm) should be replaced by (newForm),
defaulting to no such cases) and
(triples is a sequence of (oldForm, rel, altForm, newForm)
tuples defining cases where (oldForm+rel+altForm) should be
replaced by (newForm), defaulting to no such cases) ->
return a census-filter function that implements that
set of aliases ]
'''
First we transform the arguments into a pair of dictionaries
that will be used at lookup time. We also use the fixAbbr() function of the abbr module
to normalize all the bird codes, so that the singles and triples arguments do not
have to supply the uppercased, blank-filled bird codes that are
used in the censuses table.
#-- 1
# [ if singles is empty ->
# singleMap := an empty dictionary
# else ->
# singleMap := a dictionary whose keys are the first
# elements of the tuples in singles, normalized,
# and each related value is the second element of that
# tuple, normalized ]
singleMap = {}
norm = abbrMod.fixAbbr
if singles is not None:
for key, value in singles:
singleMap[norm(key)] = norm(value)
#-- 2
# [ if triples is empty ->
# tripleMap := an empty dictionary
# else ->
# tripleMap := a dictionary whose keys are a tuple made
# from the first three elements of the tuples in
# (triples), and each related value is the fourth
# element of the input tuple, with all bird codes
# normalized ]
tripleMap = {}
if triples is not None:
for form, rel, alt_form, newForm in triples:
tripleMap[(norm(form), rel, norm(alt_form))] = norm(newForm)
Now to build the actual filtering function. The function we
return will retain its bindings to the singleMap
and tripleMap we just built so it can use them
when it is called later on.
The inner function extracts the three relevant fields from the census record, changes the values if the maps so indicate, and then builds and returns a new census record with the changed values.
#-- 3
# [ result := a census-filter function that uses singleMap to
# convert single bird codes and tripleMap to convert
# compound bird codes ]
def result(census):
'''Implements the census-filter interface.
'''
#-- 1
(form, rel, alt_form) = key = (census.form, census.rel,
census.alt_form)
#-- 2
if key in tripleMap:
form = tripleMap[key]
rel = abbrMod.REL_SIMPLE
alt_form = abbrMod.BLANK_ABBR
#-- 3
if form in singleMap:
form = singleMap[form]
#-- 4
if alt_form in singleMap:
alt_form = singleMap[alt_form]
#-- 5
return pycbc.CBCData.Census(census.lat, census.lon,
census.year_no, census.year_key, census.seq_no,
form, rel, alt_form, census.age, census.sex,
census.plus, census.q, census.census)
#-- 4
return result