Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 75 additions & 39 deletions vegbank/operators/CommunityClassification.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
class CommunityClassification(Operator):
"""
Defines operations related to the exchange of community classification data
with VegBank, including community interpretations.
with VegBank, potentially including community interpretations and
classification contributors.

Community Classification: Information about a classification activity
leading one or more parties to apply a community concept to a
plot observation
Community Interpretation: The assignment of a specific community concept
to a plot observations
Classification Contributor: Party who contributed to the classification
activity, acting in some role

Inherits from the Operator parent class to utilize common default values and
methods.
Expand All @@ -24,20 +27,17 @@ def __init__(self, params):
self.table_code = "cl"
self.QUERIES_FOLDER = os.path.join(self.QUERIES_FOLDER, self.name)
self.full_get_parameters = ('limit', 'offset')
self.nested_options = ("true", "false")
self.detail_options = ("minimal", "full")

def configure_query(self, *args, **kwargs):
base_columns = {
'cl.*': "*",
'commconcept_id': "ci.commconcept_id",
'classfit': "ci.classfit",
'classconfidence': "ci.classconfidence",
'commauthority_id': "ci.commauthority_id",
'notes': "ci.notes",
'type': "ci.type",
'nomenclaturaltype': "ci.nomenclaturaltype",
'emb_comminterpretation': "ci.emb_comminterpretation",
}
query_type = self.detail
if self.with_nested == 'true':
query_type += "_nested"

base_columns = {'*': "*"}
main_columns = {}
# identify full shallow columns
main_columns['full'] = {
'cl_code': "'cl.' || cl.commclass_id",
'ob_code': "'ob.' || cl.observation_id",
Expand All @@ -47,31 +47,70 @@ def configure_query(self, *args, **kwargs):
'table_analysis': "cl.tableanalysis",
'multivariate_analysis': "cl.multivariateanalysis",
'expert_system': "cl.expertsystem",
'class_publication_rf_code': "'rf.' || cl.classpublication_id",
'class_publication_rf_label': "rf.reference_id_transl",
'class_notes': "cl.classnotes",
'cc_code': "'cc.' || cc.commconcept_id",
'comm_name': "cc.commname",
'comm_code': "cl.commcode",
'comm_framework': "cl.commframework",
'comm_level': "cl.commlevel",
'emb_comm_class': "cl.emb_commclass",
'cc_code': "'cc.' || cl.commconcept_id",
'class_fit': "cl.classfit",
'class_confidence': "cl.classconfidence",
'comm_authority_rf_code': "'rf.' || cl.commauthority_id",
'interpretation_notes': "cl.notes",
'interpretation_type': "cl.type",
'interpretation_nomenclatural_type': "cl.nomenclaturaltype",
'emb_comm_interpretation': "cl.emb_comminterpretation",
}
main_columns['minimal'] = {
'cl_code': "'cl.' || cl.commclass_id",
'ob_code': "'ob.' || cl.observation_id",
'cc_code': "'cc.' || cc.commconcept_id",
'comm_name': "cc.commname",
# identify minimal shallow colunms
main_columns['minimal'] = main_columns['full']
# identify full columns with nesting
main_columns['full_nested'] = main_columns['full'] | {
'interpretations': "interpretations",
'contributors': "contributors",
}
from_sql = """\
# identify minimal columns with nesting
main_columns['minimal_nested'] = main_columns['full_nested']
from_sql = {}
from_sql['full'] = """\
FROM cl
LEFT JOIN commconcept cc USING (commconcept_id)
LEFT JOIN view_reference_transl rf ON reference_id = cl.classpublication_id
"""
from_sql['minimal'] = from_sql['full']
from_sql_common_nested = """
LEFT JOIN LATERAL (
SELECT JSON_AGG(JSON_BUILD_OBJECT(
'py_code', 'py.' || party_id,
'party', py.party_id_transl,
'role', ar.rolecode)) AS contributors
FROM classcontributor co
LEFT JOIN view_party_transl py USING (party_id)
LEFT JOIN aux_role ar USING (role_id)
WHERE co.commclass_id = cl.commclass_id
) co ON true
""".rstrip()
from_sql['full_nested'] = from_sql['full'].rstrip() + \
from_sql_common_nested.rstrip() + """
LEFT JOIN LATERAL (
SELECT JSON_AGG(JSON_BUILD_OBJECT(
'ci_code', 'ci.' || comminterpretation_id,
'cc_code', 'cc.' || commconcept_id,
'comm_code', commcode,
'comm_name', commname,
'class_fit', classfit,
'class_confidence', classconfidence,
'comm_authority_rf_code', 'rf.' || ci.commauthority_id,
'comm_authority_name', rf.reference_id_transl,
'notes', notes,
'type', type,
'nomenclatural_type', nomenclaturaltype
)) AS interpretations
FROM comminterpretation ci
LEFT JOIN view_reference_transl rf ON rf.reference_id = ci.commauthority_id
WHERE ci.commclass_id = cl.commclass_id
) AS ci ON true
"""
from_sql['minimal_nested'] = from_sql['minimal'].rstrip() + \
from_sql_common_nested.rstrip() + """
LEFT JOIN LATERAL (
SELECT JSON_AGG(JSON_BUILD_OBJECT(
'ci_code', 'ci.' || comminterpretation_id,
'cc_code', 'cc.' || commconcept_id,
'comm_code', commcode,
'comm_name', commname
)) AS interpretations
FROM comminterpretation ci
WHERE ci.commclass_id = cl.commclass_id
) AS ci ON true
"""
order_by_sql = """\
ORDER BY cl.commclass_id
Expand All @@ -87,10 +126,7 @@ def configure_query(self, *args, **kwargs):
},
},
'from': {
'sql': """\
FROM commclass AS cl
LEFT JOIN comminterpretation ci USING (commclass_id)
""",
'sql': "FROM commclass AS cl",
'params': []
},
'conditions': {
Expand All @@ -110,11 +146,11 @@ def configure_query(self, *args, **kwargs):
}
self.query['select'] = {
"always": {
'columns': main_columns[self.detail],
'columns': main_columns[query_type],
'params': []
},
}
self.query['from'] = {
'sql': from_sql,
'sql': from_sql[query_type],
'params': []
}
2 changes: 1 addition & 1 deletion vegbank/operators/operator_parent_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def process_option_param(self, param_name, param_value, options):
option_str = ' or '.join(q_options)
elif 2 < len(q_options):
option_str = f"{', '.join(q_options[:-1])}, or {q_options[-1]}"
err_msg = f"When provided, '{param_name}' must be {option_str}"
err_msg = f"When provided, '{param_name}' must be {option_str}."
raise QueryParameterError(err_msg)

def build_query(self, by=None, count=False, searching=False, sort=False,
Expand Down
4 changes: 3 additions & 1 deletion vegbank/vegbankapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def plot_observations(ob_code):
detail (str, optional): Level of detail for the response.
Can be either 'minimal' or 'full'. Defaults to 'full'.
with_nested (str, optional): Include nested fields?
Can always be 'true' or 'false'. Defaults to 'false'.
Can be 'true' or 'false'. Defaults to 'false'.
num_taxa (int, optional): Number of taxa to return per plot observation,
in descending order of max cover if detail=minimal, and in
alphabetical order by plant name if detail=full. Defaults to 5.
Expand Down Expand Up @@ -254,6 +254,8 @@ def community_classifications(cl_code):
GET Query Parameters:
detail (str, optional): Level of detail for the response.
Can be either 'minimal' or 'full'. Defaults to 'full'.
with_nested (str, optional): Include nested fields?
Can be 'true' or 'false'. Defaults to 'false'.
limit (int, optional): Maximum number of records to return.
Defaults to 1000.
offset (int, optional): Number of records to skip before starting
Expand Down