agilescientific / striplog

Lithology and stratigraphic logs for wells or outcrop.
https://code.agilescientific.com/striplog
Apache License 2.0
204 stars 69 forks source link

Descriptions not being parsed into Components if Data also present. #135

Closed mtb-za closed 2 years ago

mtb-za commented 3 years ago

If you have additional data fields (so ones that are not one of component*, description, top, base), then components are not being generated from a description. If you only have description, top, and base, then the description is properly parsed into a list of Components, but then there is nothing in the catch-all data dictionary.

This means that like this, (note the extra facies column):

top,facies,description
70.745,3,brown shale with interbedded sandstone
70.044,0,crystalline dolomite

will populate the description field as expected, but these will not be parsed into Components. The facies column is added to the data dictionary: {'top': Position({'middle': 70.745, 'units': 'm'}), 'base': Position({'middle': 70.044, 'units': 'm'}), 'description': 'brown shale with interbedded sandstone', 'data': {'facies': 1}, 'components': []}, however the components list is empty, when it should look like [Component({'lithology': 'shale', 'colour': 'brown'}), Component({'lithology': 'sandstone', 'amount': 'interbedded'})].

The issue is in this loop:

        for iv in wanted_data:
            top = iv.pop('top')
            base = iv.pop('base', None)
            descr = iv.pop('description', '')
            if iv:
                c, d = {}, {}
                for k, v in iv.items():
                    match1 = (k[:9].lower() == 'component')
                    match2 = (k[:5].lower() == 'comp ')
                    if match1 or match2:
                        k = re.sub(r'comp(?:onent)? ', '', k, flags=re.I)
                        c[k] = v  # It's a component
                    else:
                        if v is not None:
                            d[k] = v  # It's data
                comp = [Component(c)] if c else None
                this = Interval(**{'top': top,
                                   'base': base,
                                   'description': descr,
                                   'data': d,
                                   'components': comp})
            else:
                this = Interval(**{'top': top,
                                   'base': base,
                                   'description': descr,
                                   'lexicon': lexicon})
            list_of_Intervals.append(this)

In particular, the lexicon is not passed into the Interval constructor, unless there are no additional fields.