TetraScience assay payloads can contain measurements nested under experiments, samples, panels, and other JSON containers. Write a function that recursively extracts valid measurement objects and returns a clean, flat list while preserving the nearest assay, experiment, and sample identifiers.
A measurement object is any JSON object containing both analyte and value. Normalize each valid measurement as follows:
analyte to lowercase.float values.unit strings to uppercase. Use None when unit is missing or blank.assay_id, experiment_id, and sample_id. Use None when an identifier is unavailable.Input payload is a JSON-compatible Python dictionary containing nested dictionaries, lists, strings, numbers, booleans, or None. Return a list of dictionaries with exactly these keys: assay_id, experiment_id, sample_id, analyte, value, and unit. Preserve depth-first traversal order. Identifiers found on a nested object override inherited identifiers for that object's descendants.
def clean_assay_results(payload):