sandy.fy module

This module contains all classes and functions specific for processing fission yield data.

class sandy.fy.Fy(df, **kwargs)

Bases: object

Object for fission yield data.

Attributes:
datapandas.DataFrame

Dataframe of fission yield data with the following columns:

Methods

custom_perturbation(zam, mt, e, pert)

Apply a custom perturbation to a given fission yield.

energy_table(key[, by, kind])

Pivot dataframe of tabulated fission yields as a function of energy.

_expand_zam()

Produce dataframe with three extra columns containing the Z, A and M numbers of the daughter nuclide (fission product).

_expand_zap()

Produce dataframe with three extra columns containing the Z, A and M numbers of the parent (fissioning) nuclide.

filter_by(key, value)

Apply condition to source data and return filtered results.

from_endf6(endf6[, verbose])

Extract fission yields from Endf6 instance.

to_endf6(endf6)

Update fission yields in Endf6 instance with those available in a Fy instance.

to_hdf5

Write fission yield data to hdf5 file

apply_bmatrix(zam, energy, decay_data, keep_fy_index=False)

Perform IFY = (1-B) * CFY equation to calculate IFY in a given zam for a given energy and apply into the original data.

Parameters:
zamint

ZAM number of the material to which calculations are to be applied.

energyfloat

Energy to which calculations are to be applied.

decay_datasandy.DecayData

Radioactive nuclide data for several isotopes.

keep_fy_index: `bool`, optional, default is `False`

Option that allows you to output only the CFY results that were part of the original sandy.Fy object. The default is False.

Returns:
sandy.Fy

Fission yield instance with IFY calculated for a given combination of ZAM/e/decay_data.

Notes

Note

This method applies a perturbation to certain IFYs,

since the equation IFY = (1-B) * CFY is not satisfied for all nuclei.

Examples

>>> zam = [591480, 591481, 601480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> npfy = Fy(minimal_fytest_2)
>>> npfy_pert = npfy.apply_bmatrix(942390, 5.00000e+05, decay_fytest)
>>> npfy_pert.data.query("MT==454")
    MAT   MT     ZAM     ZAP           E           FY         DFY
3  9437  454  942390  591480 5.00000e+05  8.00000e-01 4.00000e-02
4  9437  454  942390  591481 5.00000e+05  1.00000e+00 5.00000e-02
5  9437  454  942390  601480 5.00000e+05 -1.60000e+00 6.48074e-02
6  9437  454  942390  621480 5.00000e+05 -2.00000e-01 1.00000e-02
>>> zam = [591480, 591481, 601480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> npfy = Fy(minimal_fytest_2)
>>> npfy_pert = npfy.apply_bmatrix(942390, 5.00000e+05, decay_fytest, keep_fy_index=True)
>>> npfy_pert.data.query("MT==454")
    MAT   MT     ZAM     ZAP           E           FY         DFY
3  9437  454  942390  591480 5.00000e+05  8.00000e-01 4.00000e-02
4  9437  454  942390  591481 5.00000e+05  1.00000e+00 5.00000e-02
5  9437  454  942390  601480 5.00000e+05 -1.60000e+00 6.48074e-02
apply_qmatrix(zam, energy, decay_data, cut_hl=True, keep_fy_index=False)

Perform CFY = Q * IFY equation to calculate CFY in a given zam for a given energy and apply into the original data.

Parameters:
zamint

ZAM number of the material to which calculations are to be applied.

efloat

Energy to which calculations are to be applied.

decay_datasandy.DecayData

Radioactive nuclide data for several isotopes.

cut_hl: `bool`, optional, default is `True`

cut all the decay modes of the nuclides with a half life larger than 100 years.

keep_fy_indexbool, optional, default is False

Option that allows you to output only the CFY results that were part of the original sandy.Fy object.

Returns:
sandy.Fy

Fission yield instance with IFY calculated for a given combination of ZAM/e/decay_data.

Notes

Note

This method applies a perturbation to certain CFYs,

since the equation CFY = Q * IFY is not satisfied for all nuclei.

Examples

>>> zam = [591480, 591481, 601480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> npfy = Fy(minimal_fytest_2)
>>> npfy_pert = npfy.apply_qmatrix(942390, 5.00000e+05, decay_fytest, cut_hl=False)
>>> npfy_pert.data.query("MT==459")
    MAT   MT     ZAM     ZAP           E          FY         DFY
3  9437  459  942390  591480 5.00000e+05 1.00000e-01 4.00000e-02
4  9437  459  942390  591481 5.00000e+05 2.00000e-01 5.00000e-02
5  9437  459  942390  601480 5.00000e+05 6.00000e-01 6.48074e-02
6  9437  459  942390  621480 5.00000e+05 6.00000e-01 6.48074e-02
>>> npfy_pert = npfy.apply_qmatrix(942390, 5.00000e+05, decay_fytest, cut_hl=True)
>>> npfy_pert.data.query("MT==459")
    MAT   MT     ZAM     ZAP           E          FY         DFY
3  9437  459  942390  591480 5.00000e+05 1.00000e-01 4.00000e-02
4  9437  459  942390  591481 5.00000e+05 2.00000e-01 5.00000e-02
5  9437  459  942390  601480 5.00000e+05 6.00000e-01 6.48074e-02
6  9437  459  942390  621480 5.00000e+05 0.00000e+00 0.00000e+00
>>> zam = [591480, 591481, 601480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> npfy = Fy(minimal_fytest_2)
>>> npfy_pert = npfy.apply_qmatrix(942390, 5.00000e+05, decay_fytest, keep_fy_index=True)
>>> npfy_pert.data.query("MT==459")
    MAT   MT     ZAM     ZAP           E          FY         DFY
3  9437  459  942390  591480 5.00000e+05 1.00000e-01 4.00000e-02
4  9437  459  942390  591481 5.00000e+05 2.00000e-01 5.00000e-02
5  9437  459  942390  601480 5.00000e+05 6.00000e-01 6.48074e-02
custom_perturbation(zam, mt, e, pert)

Apply a custom perturbation to a given fission yield.

Parameters:
zamint

ZAM number of the material to which perturbations are to be applied.

mtint

MT reaction number of the FY to which perturbations are to be applied either 454 or 459.

efloat

Energy of the fissioning system to which which perturbations are to be applied.

pertpd.Series

Perturbation coefficients as ratio values. pert index should be the corrisponding ZAP numbers.

Returns:
Fy

Fission yield instance with applied perturbation.

Examples

>>> tape = sandy.get_endf6_file("jeff_33", 'nfpy', 'all')
>>> nfpy = Fy.from_endf6(tape)
>>> pert = pd.Series([0.9], index=[551370])
>>> nfpy_pert = nfpy.custom_perturbation(922350, 459, 0.0253, pert)
>>> comp = nfpy_pert.data.query('ZAM==922350 & ZAP==551370 & MT==459 & E==0.0253').squeeze().FY
>>> assert np.setdiff1d(nfpy_pert.data.values, nfpy.data.values) == comp
>>> pert = pd.Series([0.9, 0.5], index=[541350, 551370])
>>> nfpy_pert = nfpy.custom_perturbation(922350, 459, 0.0253, pert)
>>> comp1 = nfpy_pert.data.query('ZAM==922350 & ZAP==551370 & MT==459 & E==0.0253').squeeze().FY
>>> f1 = nfpy.data.query('ZAM==922350 & ZAP==551370 & MT==459 & E==0.0253').squeeze().FY
>>> assert f1 * 0.5 == comp1
>>> comp2 = nfpy_pert.data.query('ZAM==922350 & ZAP==541350 & MT==459 & E==0.0253').squeeze().FY
>>> f2 = nfpy.data.query('ZAM==922350 & ZAP==541350 & MT==459 & E==0.0253').squeeze().FY
>>> assert f2 * 0.9 == comp2
property data

Dataframe of fission yield data with the following columns:

  • MAT : MAT number

  • MT : MT number

  • ZAM : Z*1000 + A*10 + M for the parent (fissioning) nuclide

  • ZAPZ*1000 + A*10 + M for the daughter nuclide

    (fission product)

  • E : fissioning energy

  • FY : fission yield (fraction)

Returns:
pandas.DataFrame

tabulated fission yields

Examples

>>> Fy(minimal_fytest)
    MAT   MT     ZAM     ZAP           E          FY         DFY
0  9437  454  942390  380900 2.53000e-07 2.00000e-01 2.00000e-02
1  9437  454  942390  551370 2.53000e-07 1.80000e+00 9.00000e-02
2  9437  454  942390  380900 5.00000e+05 8.00000e-01 4.00000e-02
3  9437  454  942390  551370 5.00000e+05 1.00000e+00 5.00000e-02
4  9437  454  942390  541350 5.00000e+05 2.00000e-01 1.00000e-02
energy_table(key, by='ZAM', kind='independent')

Pivot dataframe of tabulated fission yields as a function of energy. Columns are determined by keyword argument ‘by’.

Parameters:
keyint

MAT or ZAM number used as columns of the pivot table

bystr, optional, default is ‘ZAM’

column name used as columns in the pivot table

kindstr, optional, default is ‘independent’

either ‘independent’ or ‘cumulative’

Returns:
pandas.DataFrame

tabulated fission yields

Raises:
ValueError

if kind is neither ‘independent’ nor ‘cumulative’

Notes

..note :: if a fission product has a yield at say, thermal energy but

not at fast, then a fast yield of zero will be assigned.

Examples

>>> Fy(minimal_fytest).energy_table(942390)
ZAP              380900      541350      551370
E                                              
2.53000e-07 2.00000e-01 0.00000e+00 1.80000e+00
5.00000e+05 8.00000e-01 2.00000e-01 1.00000e+00
filter_by(key, value)

Apply condition to source data and return filtered results.

Parameters:
`key`str

any label present in the columns of data

`value`int or float

value used as filtering condition

Returns:
sandy.Fy

filtered dataframe of fission yields

Notes

Note

The primary function of this method is to make sure that the filtered dataframe is still returned as a Fy object.

Examples

>>> Fy(minimal_fytest).filter_by("ZAP", 380900)
    MAT   MT     ZAM     ZAP           E          FY         DFY
0  9437  454  942390  380900 2.53000e-07 2.00000e-01 2.00000e-02
1  9437  454  942390  380900 5.00000e+05 8.00000e-01 4.00000e-02
>>> Fy(minimal_fytest).filter_by("E", 5e5)
    MAT   MT     ZAM     ZAP           E          FY         DFY
0  9437  454  942390  380900 5.00000e+05 8.00000e-01 4.00000e-02
1  9437  454  942390  551370 5.00000e+05 1.00000e+00 5.00000e-02
2  9437  454  942390  541350 5.00000e+05 2.00000e-01 1.00000e-02
classmethod from_endf6(endf6, verbose=False)

Extract fission yields from Endf6 instance.

Parameters:
endf6sandy.Endf6

object containing the ENDF-6 text

verbosebool, optional, default is False

flag to print information when reading ENDF-6 file

Returns:
sandy.Fy

fission yield object

Notes

Note

Both independent and cumulative fission product yields are loaded, if found.

Examples

>>> tape = sandy.get_endf6_file("jeff_33", "nfpy", 'all')
>>> fy = sandy.Fy.from_endf6(tape)
>>> fy.data.query("ZAM==952421 & MT==454 & E==0.0253").head()
        MAT   MT     ZAM    ZAP           E          FY         DFY
56250  9547  454  952421  10010 2.53000e-02 3.32190e-05 1.17790e-05
56251  9547  454  952421  10020 2.53000e-02 1.01520e-05 3.52080e-06
56252  9547  454  952421  10030 2.53000e-02 1.60000e-04 5.00220e-05
56253  9547  454  952421  20030 2.53000e-02 0.00000e+00 0.00000e+00
56254  9547  454  952421  20040 2.53000e-02 2.10000e-03 6.64080e-04
get_chain_yield(zam, e, decay_data, **kwargs)

Obtain chain yields from the following model: ChY = S * IFY

Parameters:
zamint

ZAM number of the fissioning nuclide.

efloat

Energy of the fissioning system.

decay_datasandy.DecayData

Radioactive nuclide data from where to obtain chain sensitivities.

kwargsdict

keyword arguments for method get_decay_chains

Returns:
pandas.Series

Chain yield obtained from ChY = S * IFY

Examples

>>> zam = [591480, 591481, 601480, 561480, 571480, 571490, 581480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> tape_nfpy = sandy.get_endf6_file("jeff_33", 'nfpy', 922350)
>>> nfpy = Fy.from_endf6(tape_nfpy)
>>> nfpy.get_chain_yield(922350, 0.0253, decay_fytest).loc[148]
0.01692277272
get_mass_yield(zam, e)

Obtain mass yields from the following model: ChY = S * IFY

Parameters:
zamint

ZAM number of the fissioning nuclide.

efloat

Energy of the fissioning system.

Returns:
pandas.Series

mass yield obtained from ChY = S * IFY

Examples

>>> tape_nfpy = sandy.get_endf6_file("jeff_33",'nfpy', 922350)
>>> nfpy = Fy.from_endf6(tape_nfpy)
>>> nfpy.get_mass_yield(922350, 0.0253).loc[148]
0.0169029147
get_mass_yield_sensitivity()

Obtain the mass yield sensitivity matrix based only on the information given in the Fy object (no decay data).

Returns:
mass_yield_sensitivitypandas.DataFrame

Mass yield sensitivity matrix. Mass number in index and ZAM of fission products in columns.

Examples

>>> zap =pd.Index([551480, 551490, 561480, 561490, 571480, 571490, 581480, 591480, 591481, 601480])
>>> tape_nfpy = sandy.get_endf6_file("jeff_33",'nfpy','all')
>>> zam = 922350
>>> energy = 0.0253
>>> conditions = {'ZAM': zam, 'E': energy}
>>> nfpy = Fy.from_endf6(tape_nfpy)._filters(conditions)
>>> nfpy.get_mass_yield_sensitivity().loc[148, zap]
551480   1.00000e+00
551490   0.00000e+00
561480   1.00000e+00
561490   0.00000e+00
571480   1.00000e+00
571490   0.00000e+00
581480   1.00000e+00
591480   1.00000e+00
591481   1.00000e+00
601480   1.00000e+00
Name: 148, dtype: float64
gls_update(zam, energy, S, y_extra, Vy_extra=None)

Perform the GLS update of fission yields and their related covariance matrix, according with https://doi.org/10.1016/j.anucene.2015.10.027. .. math:

$$
IFY_{post} = IFY_{prior} + V_{IFY_{prior}}\cdot S^T \cdot \left(S\cdot V_{IFY_{prior}}\cdot S^T + V_{y_{extra}}

ight)^{-1} cdot left(y_{extra} - y_{calc} ight)

V_{IFY_{post}} = V_{IFY_{prior}} - V_{IFY_{prior}}cdot S^T cdot left(Scdot V_{IFY_{prior}}cdot S^T + V_{y_{extra}}

ight)^{-1} cdot S cdot V_{IFY_{prior}}

$$ with $x_{post}$ the updated IFY and $x_{prior}$ the prior IFY

Parameters:
zamint

ZAM number of the material to which calculations are to be applied.

energyfloat

Energy to which calculations are to be applied.

Spandas.DataFrame

Sensitivity matrix (M, N) or sensitivity vector (N,).

y_extrapandas.Series

Extra information on output (M,). The names of the indeces must be consistent with the names of the indices of the sensitivity matrix.

Vy_extrapandas.DataFrame or pandas.Series, optional, default is None

covariance matrix with the uncertainties of the extra information, (M, M) or (1,). The names of the indeces and columns must be consistent with the names of the indices of the sensitivity matrix.

Returns:
sandy.Fy

Fy object updated with GLS for a given zam, energy, design sensitivity and new information.

sandy.CategoryCov

CategoryCov object corresponding to the updated covariance matrix adjusted with the GLS technique.

Notes

Note

If Vy_extra=None the constraint GLS update technique

will be performed.

Examples

>>> zam = [591480, 591481, 601480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> mass_numbers = [147, 148, 149]
>>> S = decay_fytest.get_chain_yield_sensitivity()
>>> chain_yields = sandy.fy.get_chain_yields()
>>> y_extra = chain_yields.query(f"A=={mass_numbers} & E=='thermal' & ZAM==922350").set_index("A").CHY
>>> std_extra_info = chain_yields.query(f"A=={mass_numbers} & E=='thermal'").set_index("A").DCHY
>>> Vy_extra = sandy.CategoryCov.from_stdev(std_extra_info).data
>>> tape = sandy.get_endf6_file("jeff_33", "nfpy", 922350)
>>> nfpy = sandy.Fy.from_endf6(tape)
>>> nfpy = sandy.Fy(nfpy.data.query(f"ZAP=={zam}"))
>>> nfpy.gls_update(922350, 0.0253, S, y_extra, Vy_extra)[0]
     MAT   MT     ZAM     ZAP           E          FY         DFY
 0  9228  454  922350  591480 2.53000e-02 8.40795e-04 2.39023e-05
 1  9228  454  922350  591481 2.53000e-02 1.39006e-02 4.22282e-05
 2  9228  454  922350  601480 2.53000e-02 5.12689e-05 5.33871e-06
 3  9228  459  922350  591480 2.53000e-02 1.66100e-02 1.21560e-04
 4  9228  459  922350  591481 2.53000e-02 3.02430e-04 1.01150e-04
 5  9228  459  922350  601480 2.53000e-02 1.69270e-02 1.18300e-04
>>> nfpy.gls_update(922350, 0.0253, S, y_extra, Vy_extra)[1]
ZAP          591480       591481       601480
ZAP
591480  5.71318e-10 -4.98686e-10 -1.34355e-12
591481 -4.98686e-10  1.78322e-09 -2.37615e-11
601480 -1.34355e-12 -2.37615e-11  2.85018e-11
>>> y_constraint = pd.Series([2], index=[0])
>>> tape = sandy.get_endf6_file("jeff_33", "nfpy", 922340)
>>> nfpy = sandy.Fy.from_endf6(tape)
>>> S = pd.DataFrame(np.ones(len(nfpy.data.query("E==400000 & MT==454").ZAP)), index=nfpy.data.query("E==400000 & MT==454").ZAP.to_list()).T
>>> nfpy_post = nfpy.gls_update(922340, 400000, S, y_constraint)[0]
>>> np.testing.assert_almost_equal(sum(nfpy_post.data.query("MT==454").FY), 2)
ishikawa_factor(zam, e, Vy_extra, kind='mass yield', decay_data=None)

Ishikawa factor to determine whether the experiment from where we obtain model sensitivity is useful to reduce the IFY uncertainty

Parameters:
zamint

ZAM number of the material to which calculations are to be applied.

efloat

Energy to which calculations are to be applied.

Vy_extra2D iterable

2D covariance matrix for y_extra (MXM).

kindstr, optional

Keyword for obtaining sensitivity. The default is ‘mass yield’.

decay_dataDecayData, optional

Object to change the model to CFY = Q*IFY or Ch_chain = S_chain*IFY, so the sensitivity (S) is Q or S_chain. The default is None, so the model is ChY = ChY_mass*IFY and the sensitivity is mass yield sensitivity.

Returns:
ishikawapd.Series

Ishikawa factor.

Results:
Ishikawa factor << 1

The extra data is not so useful and the data remain unchanged.

Ishikawa factor >> 1

The extra data very useful and the ‘posteriori’ covariance will be reduced to the same level as the integral parameter covariance.

Ishikawa factor ~ 1

The experiment is useful and the ‘posteriori’ covariance will be reduced by approximately half

Examples

>>> zam = [591480, 591481, 601480]
>>> decay_minimal = sandy.get_endf6_file("jeff_33", 'decay', zam)
>>> decay_fytest = sandy.DecayData.from_endf6(decay_minimal)
>>> CFY_var_extra = np.diag(pd.Series([1, 1, 1]))
>>> CFY_var_extra = pd.DataFrame(CFY_var_extra, index=zam, columns=zam)
>>> npfy = sandy.Fy(minimal_fytest_2)
>>> npfy.ishikawa_factor(942390, 500e3, CFY_var_extra, kind='cumulative', decay_data=decay_fytest)
591480   4.00000e-02
591481   5.00000e-02
601480   1.00000e-01
dtype: float64
>>> A = [147, 148, 149]
>>> Chain_var_extra = np.diag(pd.Series([1, 1, 1]))
>>> Chain_var_extra = pd.DataFrame(Chain_var_extra, index=A, columns=A)
>>> npfy = sandy.Fy(minimal_fytest_2)
>>> npfy.ishikawa_factor(942390, 500e3, Chain_var_extra)
147   0.00000e+00
148   1.00000e-01
149   0.00000e+00
dtype: float64
to_endf6(endf6)

Update fission yields in Endf6 instance with those available in a Fy instance.

Warning

only IFY and CFY that are originally present in the Endf6 instance are modified

Parameters:
`endf6`sandy.Endf6

Endf6 instance

Returns:
sandy.Endf6

Endf6 instance with updated IFY and CFY

Examples

>>> tape = sandy.get_endf6_file("jeff_33", "nfpy", "all")
>>> fy = sandy.Fy.from_endf6(tape)
>>> new_tape = fy.to_endf6(tape)
>>> new_tape.filter_by(listmat= [9640], listmf=[8], listmt=[454, 459])
MAT   MF  MT
9640  8   454     96245.0000 242.960000          2          0  ...
          459     96245.0000 242.960000          2          0  ...
dtype: object