docs: def _read_ascii(self):
          """Reads data and metadata from ASCII format."""
          # NOTE: ascii files store binned data using C-like ordering.
          # Dimensions are iterated like x, y, z (so z changes fastest)
  
          header_str = ''
          with open(self.path) as f:
              for line in f:
                  if line.startswith('#'):
                      header_str += line
          self._read_header(header_str)
  
          data = np.loadtxt(self.path, delimiter=',', unpack=True, ndmin=1)
  
          # separate data by statistic (neglecting bin columns when necessary)
          n_dim = len(self.dimensions)
          data = {stat: data[n_dim+i] for i, stat in enumerate(self.statistics)}
  
          # reshape data according to binning
          data_shape = [dim.n_bins for dim in self.dimensions]
          data = {k: v.reshape(data_shape) for k, v in data.items()}
  
          self.data = data