docs: def macro_state(self, micro_state):
          """Translate a micro state to a macro state
  
          Args:
              micro_state (tuple[int]): The state of the micro nodes in this
                  coarse-graining.
  
          Returns:
              tuple[int]: The state of the macro system, translated as specified
              by this coarse-graining.
  
          Example:
              >>> coarse_grain = CoarseGrain(((1, 2),), (((0,), (1, 2)),))
              >>> coarse_grain.macro_state((0, 0))
              (0,)
              >>> coarse_grain.macro_state((1, 0))
              (1,)
              >>> coarse_grain.macro_state((1, 1))
              (1,)
          """
          assert len(micro_state) == len(self.micro_indices)
  
          # TODO: only reindex if this coarse grain is not already from 0..n?
          # make_mapping calls this in a tight loop so it might be more efficient
          # to reindex conditionally.
          reindexed = self.reindex()
  
          micro_state = np.array(micro_state)
          return tuple(0 if sum(micro_state[list(reindexed.partition[i])])
                       in self.grouping[i][0] else 1
                       for i in self.macro_indices)