def get_datapoints(root):
<EOL>dataGroups = root.findall('<STR_LIT>')<EOL>if not dataGroups:<EOL><INDENT>raise MissingElementError('<STR_LIT>')<EOL><DEDENT>dataGroup = dataGroups[<NUM_LIT:0>]<EOL>property_id = {}<EOL>unit_id = {}<EOL>species_id = {}<EOL>for prop in dataGroup.findall('<STR_LIT>'):<EOL><INDENT>unit_id[prop.attrib['<STR_LIT:id>']] = prop.attrib['<STR_LIT>']<EOL>temp_prop = prop.attrib['<STR_LIT:name>']<EOL>if temp_prop not in datagroup_properties + ['<STR_LIT>']:<EOL><INDENT>raise KeyError(temp_prop + '<STR_LIT>')<EOL><DEDENT>property_id[prop.attrib['<STR_LIT:id>']] = temp_prop<EOL>if temp_prop == '<STR_LIT>':<EOL><INDENT>spec = {'<STR_LIT>': prop.find('<STR_LIT>').attrib['<STR_LIT>']}<EOL>try:<EOL><INDENT>spec['<STR_LIT>'] = prop.find('<STR_LIT>').attrib['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>warn('<STR_LIT>' + spec['<STR_LIT>'])<EOL>pass<EOL><DEDENT>species_id[prop.attrib['<STR_LIT:id>']] = spec<EOL><DEDENT><DEDENT>if not property_id:<EOL><INDENT>raise MissingElementError('<STR_LIT>')<EOL><DEDENT>datapoints = []<EOL>for dp in dataGroup.findall('<STR_LIT>'):<EOL><INDENT>datapoint = {}<EOL>if '<STR_LIT>' in property_id.values():<EOL><INDENT>datapoint['<STR_LIT>'] = {'<STR_LIT>': [], '<STR_LIT>': None}<EOL><DEDENT>for val in dp:<EOL><INDENT>if property_id.get(val.tag) in datagroup_properties:<EOL><INDENT>units = unit_id[val.tag]<EOL>if units == '<STR_LIT>':<EOL><INDENT>units = '<STR_LIT>'<EOL><DEDENT>datapoint[property_id[val.tag].replace('<STR_LIT:U+0020>', '<STR_LIT:->')] = [val.text + '<STR_LIT:U+0020>' + units]<EOL><DEDENT>elif property_id.get(val.tag) == '<STR_LIT>':<EOL><INDENT>spec = {}<EOL>spec['<STR_LIT>'] = species_id[val.tag]['<STR_LIT>']<EOL>spec['<STR_LIT>'] = species_id[val.tag].get('<STR_LIT>')<EOL>units = unit_id[val.tag]<EOL>if units in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>spec['<STR_LIT>'] = [float(val.text)]<EOL><DEDENT>elif units == '<STR_LIT>':<EOL><INDENT>warn('<STR_LIT>')<EOL>spec['<STR_LIT>'] = [float(val.text)]<EOL>units = '<STR_LIT>'<EOL><DEDENT>elif units == '<STR_LIT>':<EOL><INDENT>warn('<STR_LIT>')<EOL>spec['<STR_LIT>'] = [float(val.text) * <NUM_LIT>]<EOL>units = '<STR_LIT>'<EOL><DEDENT>elif units == '<STR_LIT>':<EOL><INDENT>warn('<STR_LIT>')<EOL>spec['<STR_LIT>'] = [float(val.text) * <NUM_LIT>]<EOL>units = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>raise KeywordError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>if datapoint['<STR_LIT>']['<STR_LIT>'] is None:<EOL><INDENT>datapoint['<STR_LIT>']['<STR_LIT>'] = units<EOL><DEDENT>elif datapoint['<STR_LIT>']['<STR_LIT>'] != units:<EOL><INDENT>raise KeywordError(<EOL>'<STR_LIT>' + units +<EOL>'<STR_LIT>' + datapoint['<STR_LIT>']['<STR_LIT>']<EOL>)<EOL><DEDENT>datapoint['<STR_LIT>']['<STR_LIT>'].append(spec)<EOL><DEDENT>else:<EOL><INDENT>raise KeywordError('<STR_LIT>' + val.tag)<EOL><DEDENT><DEDENT>datapoints.append(datapoint)<EOL><DEDENT>if len(datapoints) == <NUM_LIT:0>:<EOL><INDENT>raise MissingElementError('<STR_LIT>')<EOL><DEDENT>if len(dataGroups) > <NUM_LIT:1>:<EOL><INDENT>datapoints[<NUM_LIT:0>]['<STR_LIT>'] = []<EOL>for dataGroup in dataGroups[<NUM_LIT:1>:]:<EOL><INDENT>time_tag = None<EOL>quant_tags = []<EOL>quant_dicts = []<EOL>quant_types = []<EOL>for prop in dataGroup.findall('<STR_LIT>'):<EOL><INDENT>if prop.attrib['<STR_LIT:name>'] == '<STR_LIT:time>':<EOL><INDENT>time_dict = {'<STR_LIT>': prop.attrib['<STR_LIT>'], '<STR_LIT>': <NUM_LIT:0>}<EOL>time_tag = prop.attrib['<STR_LIT:id>']<EOL><DEDENT>elif prop.attrib['<STR_LIT:name>'] in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>quant_types.append(prop.attrib['<STR_LIT:name>'])<EOL>quant_dicts.append({'<STR_LIT>': prop.attrib['<STR_LIT>'], '<STR_LIT>': <NUM_LIT:1>})<EOL>quant_tags.append(prop.attrib['<STR_LIT:id>'])<EOL><DEDENT>else:<EOL><INDENT>raise KeywordError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>if time_tag is None or len(quant_tags) == <NUM_LIT:0>:<EOL><INDENT>raise KeywordError('<STR_LIT>')<EOL><DEDENT>time_histories = [<EOL>{'<STR_LIT:time>': time_dict, '<STR_LIT>': q, '<STR_LIT:type>': t, '<STR_LIT>': []}<EOL>for (q, t) in zip(quant_dicts, quant_types)<EOL>]<EOL>for dp in dataGroup.findall('<STR_LIT>'):<EOL><INDENT>time = None<EOL>quants = {}<EOL>for val in dp:<EOL><INDENT>if val.tag == time_tag:<EOL><INDENT>time = float(val.text)<EOL><DEDENT>elif val.tag in quant_tags:<EOL><INDENT>quant = float(val.text)<EOL>tag_idx = quant_tags.index(val.tag)<EOL>quant_type = quant_types[tag_idx]<EOL>quants[quant_type] = quant<EOL><DEDENT>else:<EOL><INDENT>raise KeywordError('<STR_LIT>'<EOL>'<STR_LIT:{}>'.format(val.tag, quant_tags))<EOL><DEDENT><DEDENT>if time is None or len(quants) == <NUM_LIT:0>:<EOL><INDENT>raise KeywordError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>for t in time_histories:<EOL><INDENT>t['<STR_LIT>'].append([time, quants[t['<STR_LIT:type>']]])<EOL><DEDENT><DEDENT>datapoints[<NUM_LIT:0>]['<STR_LIT>'].extend(time_histories)<EOL><DEDENT><DEDENT>return datapoints<EOL>
Parse datapoints with ignition delay from file.

    Args:
        root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file

    Returns:
        properties (`dict`): Dictionary with ignition delay data