Esempio n. 1
0
def condense_spectrum(dec_file):
    """
    We will explicitly ignore all continuous distributions because they do not show up as clean gamma lines.
    Note that the ENDF-B/decay/ directory stores a lot of spectra (even those with very clear lines) as continuous,
        so it may lead to the following method ignoring it.
        The workaround is just to use another library where the evaluators aren't so lazy to not use the continuous_flag=='both' :/
    """
    count = Variable(0.0, 0.0)
    if ("gamma" in dec_file['spectra']) and ("discrete"
                                             in dec_file['spectra']['gamma']):
        norm_factor = dec_file['spectra']['gamma']['discrete_normalization']
        for gamma_line in dec_file['spectra']['gamma']['discrete']:
            if np.clip(gamma_line['energy'].n,
                       *gamma_E) == gamma_line['energy'].n:
                count += photopeak_eff_curve(
                    gamma_line['energy']
                ) * gamma_line['intensity'] / 100 * norm_factor
    if ('xray' in dec_file['spectra']) and ('discrete'
                                            in dec_file['spectra']['xray']):
        norm_factor = dec_file['spectra']['xray']['discrete_normalization']
        for xray_line in dec_file['spectra']['xray']['discrete']:
            if np.clip(xray_line['energy'].n,
                       *gamma_E) == xray_line['energy'].n:
                additional_counts = photopeak_eff_curve(
                    xray_line['energy']
                ) * xray_line['intensity'] / 100 * norm_factor
                if not additional_counts.s <= additional_counts.n:
                    additional_counts = Variable(
                        additional_counts.n, additional_counts.n
                    )  # clipping the uncertainty so that std never exceed the mean. This takes care of the nan's too.
                count += additional_counts
    del dec_file['spectra']
    dec_file[
        'countable_photons'] = count  #countable photons per decay of this isotope
    return
Esempio n. 2
0
def unserialize_dict(mixed_object):
    """
    Turn the string representation of the uncertainties back into uncertainties.core.Variable 's.
    """
    if isinstance(mixed_object, dict):
        if tuple(mixed_object.keys()) == (
                "x", "y", "interpolation"
        ):  # if the mixed_object is a openmc.data.Tabulated1D object in disguise:
            mixed_object = tabulate(mixed_object)
        else:
            for key, val in mixed_object.items():
                mixed_object[key] = unserialize_dict(
                    val)  # recursively un-serialize
    elif isinstance(mixed_object, list):
        for ind, item in enumerate(mixed_object):
            mixed_object[ind] = unserialize_dict(item)
    elif isinstance(mixed_object, str):
        if '+/-' in mixed_object:  # is an uncertainties.core.Variable object
            if ')' in mixed_object:
                multiplier = float('1' + mixed_object.split(')')[1])
                mixed_object_stripped = mixed_object.split(')')[0].strip('(')
            else:
                multiplier = 1.0
                mixed_object_stripped = mixed_object
            mixed_object = Variable(*[
                float(i) * multiplier
                for i in mixed_object_stripped.split('+/-')
            ])
        else:
            pass  # just a normal string
    else:  # unknown type
        pass
    return mixed_object
Esempio n. 3
0
def build_decay_chain_tree(decay_parent,
                           decay_dict,
                           decay_constant_threshold=1E-23):
    """
    Build the entire decay chain for a given starting isotope.

    decay_parent : str
        names of the potentially unstable nuclide
    decay_dict : dictionary
        the entire decay_dict containing all of the that there is.
    """
    if not decay_parent in decay_dict:
        # decay_dict does not contain any decay data record about the specified isotope (decay_parent), meaning it is (possibly) stable.
        return_dict = {
            'name': decay_parent,
            'decay_constant': Variable(0.0, 0.0),
            'countable_photons': Variable(0.0, 0.0),
            'modes': {}
        }
    else:  # decay_dict contains the specified decay_parent
        parent = decay_dict[decay_parent]
        return_dict = {
            'name': decay_parent,
            'decay_constant': parent['decay_constant'],
            'countable_photons': parent['countable_photons']
        }  # countable_photons per decay of this isotope
        if decay_dict[decay_parent][
                'decay_constant'] <= decay_constant_threshold:
            # if this isotope is rather stable.
            return return_dict
        else:
            return_dict['modes'] = []
            for name, branching_ratio in decay_dict[decay_parent][
                    'branching_ratio'].items():
                if name != decay_parent:
                    return_dict['modes'].append({
                        'daughter':
                        build_decay_chain_tree(name, decay_dict),
                        'branching_ratio':
                        branching_ratio
                    })
    return return_dict
Esempio n. 4
0
def extract_decay(dec_file):
    """
    extract the useful information out of an openmc.data.Decay entry
    """
    half_life = Variable(
        np.clip(dec_file.half_life.n, 1E-23, None),
        dec_file.half_life.s)  # increase the half-life to a non-zero value.
    decay_constant = ln(2) / (half_life)
    modes = {}
    for mode in dec_file.modes:
        modes[mode.daughter] = mode.branching_ratio
    return dict(decay_constant=decay_constant,
                branching_ratio=modes,
                spectra=dec_file.spectra)
Esempio n. 5
0
    def decode(self, o):
        """
        Catch the uncertainties
        Edit: This class doesn't work because the cpython/decoder.py is not written in a open-for-expansion principle.
        I suspect this is because turning variables (which aren't strings) into strings is an
            imporper way to use jsons; but I don't have any other solutions for EncoderOpenMC.

        In any case, DecoderOpenMC will be replaced by unserialize_dict below.
        """
        if '+/-' in o:
            if ')' in o:
                multiplier = float('1' + o.split(')')[1])
                o = o.split(')')[0].strip('(')
            else:
                multiplier = 1.0
            return Variable(*[float(i) * multiplier for i in o.split('+/-')])
        else:
            return super().decode(o)
Esempio n. 6
0
def linearize_decay_chain(decay_file):
    """
    Return a comprehensive list of path-to-nodes. Each path starts from the origin, and ends at the node of interest.
    Each node in the original graph must be must be recorded as the end node exactly once.
    The initial population is always assumed as 1.
    """
    self_decay = IsotopeDecay(
        [decay_file['name']],
        [Variable(1.0, 0.0)],  # branching ratio dummy value
        [decay_file['decay_constant']],
        decay_file['countable_photons'])
    all_chains = [self_decay]
    if 'modes' in decay_file:  # expand the decay modes if there are any.
        for mode in decay_file['modes']:
            this_branch = linearize_decay_chain(
                mode['daughter']
            )  # note that this is a list, so we need to unpack it.
            for subbranch in this_branch:
                subbranch.branching_ratios[0] = mode['branching_ratio']
                all_chains.append(self_decay + subbranch)
    return all_chains  # returns a list