code: def apply_uncertainties(self, branch_ids, source_group):
          
          branchset = self.root_branchset
          branchsets_and_uncertainties = []
          branch_ids = list(branch_ids[::-1])
  
          while branchset is not None:
              branch = branchset.get_branch_by_id(branch_ids.pop(-1))
              if not branchset.uncertainty_type == 'sourceModel':
                  branchsets_and_uncertainties.append((branchset, branch.value))
              branchset = branch.child_branchset
  
          if not branchsets_and_uncertainties:
              return source_group  # nothing changed
  
          sg = copy.deepcopy(source_group)
          sg.applied_uncertainties = []
          sg.changed = numpy.zeros(len(sg.sources), int)
          for branchset, value in branchsets_and_uncertainties:
              for s, source in enumerate(sg.sources):
                  changed = branchset.apply_uncertainty(value, source)
                  if changed:
                      sg.changed[s] += changed
                      sg.applied_uncertainties.append(
                          (branchset.uncertainty_type, value))
          return sg
docs: Parse the path through the source model logic tree and return
          "apply uncertainties" function.
  
          :param branch_ids:
              List of string identifiers of branches, representing the path
              through source model logic tree.
          :param source_group:
              A group of sources
          :return:
              A copy of the original group with modified sources