<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _read_header(self, header_str):
 """Reads metadata from the header."""


        # regular expressions
        re_float = '[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?'
        re_uint = '\d+'
        re_binning = '{d} in (?P<nbins>' + re_uint + ') bin[ s] '
        re_binning += 'of (?P<binwidth>' + re_float + ') {unit}'

        # map of dimensions and units
        dim_units = {
            'X': 'cm',
            'Y': 'cm',
            'Z': 'cm',
            'R': 'cm',
            'Phi': 'deg',
            'Theta': 'deg',
        }

        # retrieve binning info
        self.dimensions = []
        for line in header_str.splitlines():

            for dim, unit in dim_units.items():
                re_tmp = re_binning.format(d=dim, unit=unit)
                regex = re.compile(re_tmp)
                match = regex.search(line)

                if match:
                    N = int(match.group('nbins'))
                    width = float(match.group('binwidth'))
                    dimension = BinnedDimension(dim, unit, N, width)
                    self.dimensions.append(dimension)

        # retrieve scored quantity info
        re_score_unit = '# (?P<quant>.+) \( (?P<unit>.+) \) : (?P<stats>.+)'
        re_score_unitless = '# (?P<quant>.+) : (?P<stats>.+)'
        regex_unit = re.compile(re_score_unit)
        regex_unitless = re.compile(re_score_unitless)

        for line in header_str.splitlines():

            match = regex_unit.search(line)
            if match:
                self.quantity = match.group('quant')
                self.unit = match.group('unit')
                self.statistics = match.group('stats').split()
                break

            match = regex_unitless.search(line)
            if match:
                self.quantity = match.group('quant')
                self.unit = None
                self.statistics = match.group('stats').split()
                break