Exemple #1
0
    def toPointwise_withLinearXYs(self,
                                  accuracy=None,
                                  lowerEps=0,
                                  upperEps=0,
                                  invert=False):

        eps = 1e-6
        ptw = XYs2d(XYs2d.defaultAxes(energyUnit=self.domainUnit()))
        if (invert):
            ptw.append(
                XYsModule.XYs1d([[-1, 2 / eps], [eps - 1, 0.]],
                                value=self.domainMin(),
                                accuracy=1e-6))
            ptw.append(
                XYsModule.XYs1d([[-1, 2 / eps], [eps - 1, 0.]],
                                value=self.domainMax(),
                                accuracy=1e-6))
        else:
            ptw.append(
                XYsModule.XYs1d([[1 - eps, 0.], [1, 2 / eps]],
                                value=self.domainMin(),
                                accuracy=1e-6))
            ptw.append(
                XYsModule.XYs1d([[1 - eps, 0.], [1, 2 / eps]],
                                value=self.domainMax(),
                                accuracy=1e-6))
        return (ptw)
Exemple #2
0
def gammaDeltaDistribution(energy):

    deltaEnergy = float("1e%s" % ("%.0e" % (energy * energyEps)).split('e')[1])
    eMin, eMax = energy - deltaEnergy, energy + deltaEnergy
    if (eMin < 0):
        return (XYsModule.XYs([[energy, 1.], [eMax, 0.]]).normalize())
    return (XYsModule.XYs([[eMin, 0.], [energy, 1], [eMax, 0.]]).normalize())
Exemple #3
0
def KalbachMannDataToString( KalbachMannData, energy_in_unit ) :

    nForm = 4
    if( KalbachMannData.aSubform.data is None ) : nForm = 3
    if( nForm == 4 ) : raise Exception( 'This is currently not implemented' )

    fSubform = KalbachMannData.fSubform.data
    rSubform = KalbachMannData.rSubform.data

    factor = fSubform.domainUnitConversionFactor( energy_in_unit ) # Energies passed to get_transfer must be in energy_in_unit, traditionally MeV.
    _fSubform = multiD_XYsModule.XYs2d( )
    for xys in fSubform :
        _xys = XYsModule.XYs1d( data = xys.scaleOffsetXAndY( xScale = factor, yScale = 1 / factor ), value = factor * xys.value )
        _fSubform.append( _xys )

    _rSubform = multiD_XYsModule.XYs2d( )
    for xys in rSubform :
        _xys = XYsModule.XYs1d( data = xys.scaleOffsetXAndY( xScale = factor ), value = factor * xys.value )
        _rSubform.append( _xys )

    s  = startOfNewData
    s += "Kalbach probabilities: n = %s\n" % len( _fSubform )
    s += "Incident energy interpolation: %s %s\n" % ( linlin,
            GND2ProcessingInterpolationQualifiers[standardsModule.interpolation.unitBaseToken] )
    s += "Outgoing energy interpolation: %s\n" % fSubform[0].interpolation
    s += threeDListToString( _fSubform )

    s += "Kalbach r parameter: n = %s\n" % len( rSubform )
    s += "Incident energy interpolation: %s %s\n" % ( rSubform.interpolation, 
            GND2ProcessingInterpolationQualifiers[standardsModule.interpolation.unitBaseUnscaledToken] )
    s += "Outgoing energy interpolation: %s\n" % rSubform[0].interpolation
    s += threeDListToString( _rSubform )

    return( s )
Exemple #4
0
    def divideIgnoring0DividedBy0(self, other):

        if (isinstance(self, XYsModule.XYs1d)
                and isinstance(other, XYsModule.XYs1d)):
            d = self.union(
                other.domainSlice(domainMin=self.domainMin,
                                  domainMax=self.domainMax))
            result = []
            for p in d:
                vp = other.evaluate(p[0])
                if (vp == 0):
                    if (p[1] != 0):
                        raise Exception(
                            'Divide non-zero number by zero at %e' % p[0])
                else:
                    p[1] = p[1] / vp
                result.append([p[0], p[1]])
            return (XYsModule.pointwiseXY(data=result))

        elif (isinstance(self, regionsModule.regions1d)
              and isinstance(other, regionsModule.regions1d)
              and len(self) == len(other)):
            regions = regionsModule.regions1d()
            for idx in range(len(self)):
                regions.append(
                    XYsModule.XYs1d(
                        data=divideIgnoring0DividedBy0(self[idx], other[idx])))
            return regions

        else:
            raise NotImplementedError('Divide XYs1d by regions or vice-versa')
Exemple #5
0
    def toPointwise_withLinearXYs(self, **kwargs):

        accuracy = xDataBaseModule.getArguments(kwargs,
                                                {'accuracy': 1e-6})['accuracy']

        ptw = XYs2d(defaultAxes(self.domainUnit))
        ptw.append(
            XYsModule.XYs1d([[1 - accuracy, 0.], [1, 2 / accuracy]],
                            value=self.domainMin))
        ptw.append(
            XYsModule.XYs1d([[1 - accuracy, 0.], [1, 2 / accuracy]],
                            value=self.domainMax))
        return (ptw)
Exemple #6
0
    def averageForwardMomentum(self, sqrt_2_ProductMass):

        averageMu = [[pdfOfMuAtEp.value,
                      pdfOfMuAtEp.averageMu()] for pdfOfMuAtEp in self]
        return (sqrt_2_ProductMass * float(
            XYsModule.XYs1d(averageMu, interpolation=self.interpolation).
            integrateWithWeight_sqrt_x()))
Exemple #7
0
def calculateMomentumPoints( massInE, EMin, EMax, energyUnit, accuracy = 1e-4 ) :
    """
    This is a temporary function (hopefully) to calculate momentum vs E.
    What is really needed is a function like rriint in mcfgen.
    """

    import math

    momentum = []

    def insertPointIfNeeded( Ep1, Ep2 ) :

        E1, p1 = Ep1
        E2, p2 = Ep2
        s = ( p2 - p1 ) / ( E2 - E1 )
        Em = massInE / ( 2. * s * s )
        pc = math.sqrt( 2 * massInE * Em )
        pi = s * ( Em - E1 ) + p1
        if( abs( pi / pc  - 1 ) > accuracy ) :
            m = [ Em, pc ]
            momentum.append( m )
            insertPointIfNeeded( Ep1, m )
            insertPointIfNeeded( m, Ep2 )

    if( massInE == 0 ) :            # gammas
        momentum.append( [ EMin, EMin ] )
        momentum.append( [ EMax, EMax ] )
    else :
        momentum.append( [ EMin, math.sqrt( 2 * massInE * EMin ) ] )
        momentum.append( [ EMax, math.sqrt( 2 * massInE * EMax ) ] )
        insertPointIfNeeded( momentum[0], momentum[1] )
    momentum.sort( )
    axes = axesModule.axes( labelsUnits = { 0 : [ 'energy_in', energyUnit ], 1 : [ 'momentum', energyUnit + '/c' ] } )
    return( XYsModule.XYs1d( data = momentum, axes = axes, accuracy = accuracy ) )
Exemple #8
0
    def getW_XYs(self):

        from xData import axes as axesModule
        from xData import XYs as XYsModule
        from xData import multiD_XYs as multiD_XYsModule

        xUnit, yUnit, zUnit = '', '', ''
        if (self.xUnit is not None): xUnit = self.xUnit
        if (self.yUnit is not None): yUnit = self.yUnit
        if (self.zUnit is not None): zUnit = self.zUnit
        axes_3d = axesModule.axes(3)
        axes_3d[0] = axesModule.axis('z', 0, zUnit)
        axes_3d[1] = axesModule.axis('y', 0, yUnit)
        axes_3d[2] = axesModule.axis('x', 0, xUnit)
        w_xys = multiD_XYsModule.multiD_XYs(axes=axes_3d)

        axes_2d = axesModule.axes()
        axes_2d[0] = axes_3d[0]
        axes_2d[1] = axes_3d[1]

        for ix, x in enumerate(self.x):
            xys = [[y, self.z[iy][ix]] for iy, y in enumerate(self.y)]
            w_xys[ix] = XYsModule.XYs(xys,
                                      axes=axes_2d,
                                      accuracy=1e-3,
                                      value=x)
        return (w_xys)
Exemple #9
0
    def getFluxAtLegendreOrder(self, order):

        axes = axesModule.axes()
        axes[1] = self.axes[2].copy([])
        axes[0] = self.axes[0].copy([])
        for LS in self:
            if (len(LS) > 1): raise Exception('FIXME -- next line is wrong.')
        return (XYsModule.XYs1d([[LS.value, LS[0]] for LS in self], axes=axes))
Exemple #10
0
    def averageEnergy(self):

        integralOfMu = [[pdfOfMuAtEp.value,
                         pdfOfMuAtEp.integrate()] for pdfOfMuAtEp in self]
        return (float(
            XYsModule.XYs1d(
                integralOfMu,
                interpolation=self.interpolation).integrateWithWeight_x()))
Exemple #11
0
def energyFunctionToString( energyData, weight = None ) :

    def getParameter( data, label ) :

        _linlin = data.toPointwise_withLinearXYs( lowerEps = lowerEps, upperEps = upperEps )
        sData = [ startOfNewData, "%s: n = %d" % ( label, len( _linlin ) ) ]
        sData.append( 'Interpolation: %s' % linlin )
        for x, y in _linlin : sData.append( '%s %s' % ( x, y ) )
        return( sData )

    sData = []
    if( isinstance( energyData, ( energyModule.simpleMaxwellianFissionSpectrum, energyModule.evaporationSpectrum, energyModule.WattSpectrum ) ) ) :
        sData.append( 'U: %s' % energyData.U.getValueAs( energyData.parameter1.data.axes[-1].unit ) )

    parameter1 = energyData.parameter1.data.toPointwise_withLinearXYs( accuracy = 1e-5, lowerEps = lowerEps, upperEps = upperEps )

    if( energyData.parameter2 is not None ) :
        parameter2 = energyData.parameter2.data.toPointwise_withLinearXYs( accuracy = 1e-5, lowerEps = lowerEps, upperEps = upperEps )

    if( weight is None ) :
        axes = axesModule.axes( )
        weight = XYsModule.XYs1d( data = [ [ parameter1.domainMin, 1. ], [ parameter1.domainMax, 1. ] ], axes = axes )
    else :
        weight = weight.weight
    sData += twoDToString( "weight", weight, addExtraBlankLine = False )

    if( isinstance( energyData, energyModule.generalEvaporationSpectrum ) ) :
        sProcess = 'Process: general evaporation\n'
        sSpecific = ''
        sData += getParameter( parameter1, 'Theta' )
        sData += getParameter( parameter2, 'g' )
    elif( isinstance( energyData, energyModule.simpleMaxwellianFissionSpectrum ) ) :
        sProcess = 'Process: Maxwell spectrum\n'
        sSpecific = ''
        sData += getParameter( parameter1, 'Theta' )
    elif( isinstance( energyData, energyModule.evaporationSpectrum ) ) :
        sProcess = 'Process: Evaporation spectrum\n'
        sSpecific = 'Interpolate Eout integrals: false\n'
        sSpecific += 'Quadrature method: Gauss6\n'
        sData += getParameter( parameter1, 'Theta' )
    elif( isinstance( energyData, energyModule.WattSpectrum ) ) :
        sProcess = 'Process: Watt spectrum\n'
        sSpecific = 'Interpolate Eout integrals: false\n'
        sSpecific += 'Conserve: number\n'
        sData += getParameter( parameter1, 'a' )
        sData += getParameter( parameter2, 'b' )
    elif( isinstance( energyData, energyModule.MadlandNix ) ) :
        sProcess = 'Process: Madland-Nix spectrum\n'
        sSpecific  = 'Quadrature method: adaptive\n'
        sSpecific += 'Interpolate Eout integrals: false\n'
        sSpecific += 'Conserve: number\n'
        sSpecific += 'EFL: %s\n' % energyData.EFL.getValueAs( energyData.parameter1.data.axes[-1].unit )
        sSpecific += 'EFH: %s\n' % energyData.EFH.getValueAs( energyData.parameter1.data.axes[-1].unit )
        sData += getParameter( parameter1, 'TM' )
    else :
        raise Exception( 'Unsupport energy functional = %s' % energyData.moniker )
    sData.append( '' )
    return( sProcess, sSpecific, startOfNewData + '\n'.join( sData ) )
Exemple #12
0
def calculateDepositionEnergyFromEpP(E, EpP):
    "EpP is a list of [ E', P(E') ]"

    axes = axesModule.axes()
    axes[0] = axesModule.axis('a', 0, EpP.axes[0].unit)
    axes[1] = axesModule.axis('b', 1, EpP.axes[1].unit)
    Ep = XYsModule.XYs1d(data=[[EpP[0][0], EpP[0][0]],
                               [EpP[-1][0], EpP[-1][0]]],
                         axes=axes)
    return (float(EpP.integrateTwoFunctions(Ep)))
Exemple #13
0
def grouped_values_to_XYs( groupBdries, valueList, \
                           domainUnit='eV', domainName='energy_in', rangeUnit='b', rangeName='crossSection', \
                           accuracy=upperEps, domainMin=1e-5, domainMax=20.0):
    if len(groupBdries) != len(valueList)+1:
        raise ValueError("Group boundries and value lists have incompatable lengths: len(bdries)=%i, len(vals)=%i"%(len(groupBdries),len(valueList)))
    return XYs.XYs1d(\
        data=[groupBdries, [valueList[0]]+valueList], \
        dataForm="xsandys", \
        interpolation=standards.interpolation.flatToken, \
        axes=XYs1d.defaultAxes(labelsUnits={ \
                XYs.yAxisIndex : ( rangeName, rangeUnit ), \
                XYs.xAxisIndex : ( domainName, domainUnit ) }) )
Exemple #14
0
    def __init__(self, angularEnergy_):

        self.productFrame = angularEnergy_.getProductFrame()
        axes_ = axes.defaultAxes(3)
        axes_[0] = angularEnergy_.axes[0]
        axes_[1] = angularEnergy_.axes[1]
        axes_[2] = axes.axis("P(mu|energy_in)", 2, "")
        W_XYs.W_XYs.__init__(self, axes_)

        for w_xys in angularEnergy_:
            P_mu = [[xys.value, xys.integrate()] for xys in w_xys]
            self.append(
                XYs.XYs(XYs.XYs.defaultAxes(), P_mu, 1e-3, value=w_xys.value))
Exemple #15
0
def addData( endlZA, X1, temperature, energyMin_MeV, energyMax_MeV, I0Data, I1Data, I3Data, halflife = None ) :

    endlFile = getEndlFile( endlZA, 0, 11, 0, 1 )
    data = [ [ energy, xSec ] for energy, xSec in I0Data ]
    if( data[0][0] > energyMin_MeV ) :
        if( data[0][1] != 0 ) : data.insert( 0, [ data[0][0], 0 ] )
        data.insert( 0, [ energyMin_MeV, 0 ] )
    if( data[-1][0] < energyMax_MeV ) :
        if( data[-1][1] != 0 ) : data.append( [ data[-1][0], 0 ] )
        data.append( [ energyMax_MeV, 0 ] )
    endlData = endlFile.addData( data, Q = 0, X1 = X1, temperature = temperature, halflife = halflife )
    endlData.setFormat( 15 )

    if( I1Data[0][0] > energyMin_MeV ) : I1Data.insert( 0, [ energyMin_MeV, copy.copy( I1Data[0][1] ) ] )
    if( I1Data[-1][0] < energyMax_MeV ) : I1Data.append( [ energyMax_MeV, copy.copy( I1Data[-1][1] ) ] )
    _I1Data = []
    for energy, PofMu in I1Data :
        PofMu = XYsModule.XYs1d( PofMu ).normalize( )
        _I1Data.append( [ energy, [ [ P, Mu ] for P, Mu in PofMu ] ] )

    endlFile = getEndlFile( endlZA, 1, 11, 1, 1 )
    endlData = endlFile.addData( _I1Data, Q = 0, X1 = X1, temperature = temperature, halflife = halflife )
    endlData.setFormat( 15 )

    if I3Data is not None:
        if( I3Data[0][0] > energyMin_MeV ) : I3Data.insert( 0, [ energyMin_MeV, copy.copy( I3Data[0][1] ) ] )
        if( I3Data[-1][0] < energyMax_MeV ) : I3Data.append( [ energyMax_MeV, copy.copy( I3Data[-1][1] ) ] )

        _I3Data = []
        for energy, PofEprimeMu in I3Data:
            tmp = []
            for mu, PofEprime in PofEprimeMu:
                PofEprime = XYsModule.XYs1d( PofEprime ).normalize( )
                tmp.append( [ mu, [ [ Ep, P ] for Ep, P in PofEprime ] ] )
            _I3Data.append( [ energy, tmp ] )

        endlFile = getEndlFile( endlZA, 1, 11, 3, 1 )
        endlData = endlFile.addData( _I3Data, Q = 0, X1 = X1, temperature = temperature, halflife = halflife )
        endlData.setFormat( 15 )
Exemple #16
0
def uncorrelated_EMuP_EEpP_TransferMatrix( style, tempInfo, crossSection, productFrame, angularData, energyData, 
        multiplicity, comment = None, weight = None ) :

    logFile = tempInfo['logFile']
    workDir = tempInfo['workDir']

    sSpecific = ''
    if( isinstance( energyData, energyModule.functionalBase ) ) :
        sProcess, sSpecific, sData = energyFunctionToString( energyData, weight = weight )
        weight = None
    elif( isinstance( energyData, energyModule.weightedFunctionals ) ) :
        TM1s, TMEs = [], []
        for weight in energyData :
            TM1, TME = uncorrelated_EMuP_EEpP_TransferMatrix( style, tempInfo, crossSection, productFrame, angularData, 
                    weight.functional, multiplicity, comment = comment, weight = weight )
            TM1s.append( TM1 )
            TMEs.append( TME )
        TM1 = addTMs( TM1s )
        TME = addTMs( TMEs )
        return( TM1, TME )
    elif( isinstance( energyData, energyModule.regions2d ) ) :
        TM1s, TMEs = [], []
        axes = axesModule.axes( )
        for i1, region in enumerate( energyData ) :
            weight = XYsModule.XYs1d( data = [ [ region.domainMin, 1. ], [ region.domainMax, 1. ] ], axes = axes )
            tempInfo['workFile'].append( 'r%s' % i1 )
            try :
                TM1, TME = uncorrelated_EMuP_EEpP_TransferMatrix( style, tempInfo, crossSection, productFrame, angularData,
                        region, multiplicity, comment = comment, weight = weight )
            except :
                del tempInfo['workFile'][-1]
                raise
            del tempInfo['workFile'][-1]
            TM1s.append( TM1 )
            TMEs.append( TME )
        TM1 = addTMs( TM1s )
        TME = addTMs( TMEs )
        return( TM1, TME )
    elif( isinstance( energyData, energyModule.primaryGamma ) ) :
        return( primaryGammaAngularData( style, tempInfo, crossSection, energyData, angularData, multiplicity = multiplicity, comment = comment ) )
    else :
        if( angularData.isIsotropic() ) :
            sProcess = "Process: isotropic table\n"
            sData = EEpPDataToString( energyData )
        else:
            sProcess = "Process: 'Uncorrelated energy-angle data transfer matrix'\n"
            sData = angularToString( angularData, crossSection )
            sData += EEpPDataToString( energyData )
    sCommon = commonDataToString( comment, style, tempInfo, crossSection, productFrame, multiplicity = multiplicity, weight = weight )
    s = versionStr + '\n' + sProcess + sSpecific + sCommon + sData
    return( executeCommand( logFile, transferMatrixExecute, s, workDir, tempInfo['workFile'] ) )
Exemple #17
0
    def getUncertaintyVector( self, theData=None, relative=True ):
        """ 
        Get an XYs1d object containing uncertainty for this matrix.
        Convert relative/absolute if requested (if so, must also pass central values as theData)

        Examples:

            - if the covariance matrix is relative and we want relative uncertainty vector, just do:
            
                > matrix.getUncertaintyVector()
                
            - if we want the absolute matrix instead:
            
                > matrix.getUncertaintyVector( theData=<XYs1d instance>, relative=False )
                
        """
        if not self.isSymmetric():
            raise ValueError("getUncertaintyVector only applies to symmetric matrices!")
        energies = list( self.matrix.axes[-1].values )
        diag = numpy.diagonal( self.matrix.array.constructArray() ).copy()
        diag[ diag < 0.0 ] = 0.0
        diag = list( numpy.sqrt( diag ) )
        diag.append( diag[-1] )                             # point corresponding to final energy bin
        yunit = self.matrix.axes[0].unit
        if yunit != '': # get square root of the unit
            yunit = PQU.PQU(1,yunit).sqrt().getUnitSymbol()
        axes_ = axesModule.axes(
                                 labelsUnits={1:('energy_in',self.matrix.axes[2].unit),
                                              0:('uncertainty',yunit)} )
        uncert = XYsModule.XYs1d( zip(energies,copy.deepcopy(diag)), axes=axes_, interpolation='flat',
                                accuracy=0.0001, )    # what should accuracy be set to?
        uncert = uncert.changeInterpolation('lin-lin',None,1e-8,1e-8)

        # do we need to convert absolute->relative or vice versa?
        if (relative and self.type==tokens.absoluteToken) or (not relative and self.type==tokens.relativeToken):
            if theData is None:
                theData = self.ancestor.rowData.link.toPointwise_withLinearXYs(1e-8,1e-8)
            try:
                theData = theData.toPointwise_withLinearXYs(1e-8,1e-8)
                uncert, theData = uncert.mutualify(1e-8, 1e-8, False, theData, 1e-8, 1e-8, False)
                if relative: #convert absolute to relative
                    uncert /= theData
                else: #relative to absolute
                    uncert *= theData
            except Exception as err:
                print len( uncert ), uncert.copyDataToXYs()[0], uncert.copyDataToXYs()[-1]
                print len( theData ), theData.copyDataToXYs()[0], theData.copyDataToXYs()[-1]
                raise Exception( err.message )
        return uncert
Exemple #18
0
    def __init__( self, angularEnergy ) :

        self.__productFrame = angularEnergy.productFrame
        axes = axesModule.defaultAxes( 3 )
        axes2d[2] = angularEnergy.axes[2]
        axes2d[1] = angularEnergy.axes[1]
        axes2d[0] = axesModule.axis( "P(mu|energy_in)", 0, "" )
        axes1d = XYsModule.XYs1d.defaultAxes( )
        axes1d[0] = axes2d[0]
        axes1d[1] = axes2d[1]
        multiD_XYsModule.XYs2d.__init__( self, axes = axes2d )

        for P_EpGivenMu in angularEnergy :
            P_mu = [ [ xys.value, xys.integrate( ) ] for xys in P_EpGivenMu ]
            self.append( XYsModule.XYs1d( data = P_mu, axes = axes1d, accuracy = 1e-3, value = P_EpGivenMu.value ) )
Exemple #19
0
    def makeGrouped(self, processInfo, tempInfo):

        projectile, target = processInfo.getProjectileName(
        ), processInfo.getTargetName()
        groups = processInfo.getParticleGroups(projectile)
        energyUnit = tempInfo['crossSection'].domainUnit()
        axes = axesModule.axes(labelsUnits={
            0: ['energy_in', energyUnit],
            1: ['energy', energyUnit]
        })
        domainMin, domainMax = tempInfo['crossSection'].domain()
        energy = XYsModule.XYs1d(data=[[domainMin, domainMin],
                                       [domainMax, domainMax]],
                                 axes=axes,
                                 accuracy=1e-8)
        axes, grouped_ = miscellaneousModule.makeGrouped(
            self, processInfo, tempInfo, energy)
        self.addForm(grouped(axes, grouped_))
        axes, grouped_ = miscellaneousModule.makeGrouped(
            self, processInfo, tempInfo, energy, normType='groupedFlux')
        self.addForm(groupedWithCrossSection(axes, grouped_))
Exemple #20
0
def twoBodyTransferMatrix( style, tempInfo, productFrame, crossSection, angularData, Q, weight = None, comment = None ) :
    """
    Generate input and call processing code to generate a transfer matrix for two-body angular distribution.
    If the distribution is actually made up of two different forms in different energy regions, this function
    calls itself in the two regions and sums the result.
    """

    if( isinstance( angularData, angularModule.isotropic ) ) : angularData = angularData.toPointwise_withLinearXYs( )

    if( isinstance( angularData, angularModule.XYs2d ) ) :
        TM1, TME = twoBodyTransferMatrix2( style, tempInfo, crossSection, angularData, Q, productFrame, comment = comment )
    elif( isinstance( angularData, angularModule.regions2d ) ) :
        TM1s, TMEs = [], []
        lowestBound, highestBound = angularData[0].domainMin, angularData[-1].domainMax
        weightAxes = axesModule.axes( )
        for iRegion, region in enumerate( angularData ) :
                if( iRegion == 0 ) :
                    weightData = [ [ lowestBound, 1 ], [ region.domainMax, 0 ], [ highestBound, 0 ] ]
                elif( iRegion == len( angularData ) - 1 ) :
                    weightData = [ [ lowestBound, 0 ], [ region.domainMin, 1 ], [ highestBound, 1 ] ]
                else :
                    weightData = [ [ lowestBound, 0 ], [ region.domainMin, 1 ], [ region.domainMax, 0 ], [ highestBound, 0 ] ]
                _weight = XYsModule.XYs1d( data = weightData, axes = weightAxes )

                tempInfo['workFile'].append( 'r%s' % iRegion )
                try :
                    TM1, TME = twoBodyTransferMatrix2( style, tempInfo, crossSection, region, Q,
                            productFrame, weight = _weight, comment = comment )
                except :
                    del tempInfo['workFile'][-1]
                    raise
                del tempInfo['workFile'][-1]
                TM1s.append( TM1 )
                TMEs.append( TME )
        TM1 = addTMs( TM1s )
        TME = addTMs( TMEs )
    else :
        raise Exception( 'Unsupported P(mu|E) = %s' % angularData.moniker )

    return( TM1, TME )
Exemple #21
0
    def check(self, info):
        from fudge.gnd import warning
        from pqu import PQU
        warnings = []
        axes = axesModule.axes()
        axes[0] = self.axes[-2]
        axes[1] = self.axes[-1]

        for index, energy_in in enumerate(self):
            integral = float(
                XYsModule.XYs1d([(eout.value, eout.coefficients[0])
                                 for eout in energy_in],
                                axes=axes,
                                accuracy=0.001).integrate())
            if abs(integral - 1.0) > info['normTolerance']:
                warnings.append(
                    warning.unnormalizedDistribution(
                        PQU.PQU(energy_in.value, axes[0].unit), index,
                        integral, self.toXLink()))
            minProb = min([
                xy.toPointwise_withLinearXYs(0.001).rangeMin()
                for xy in energy_in
            ])
            if minProb < 0:
                warnings.append(
                    warning.negativeProbability(PQU.PQU(
                        energy_in.value, axes[0].unit),
                                                value=minProb,
                                                obj=energy_in))
            if self.interpolationQualifier is standardsModule.interpolation.unitBaseToken:
                # check for more than one outgoing distribution integrating to 0 at high end of incident energies
                integrals = [eout.integrate() for eout in energy_in]
                for idx, integral in enumerate(integrals[::-1]):
                    if integral != 0: break
                if idx > 1:
                    warnings.append(
                        warning.extraOutgoingEnergy(PQU.PQU(
                            energy_in.value, axes[-1].unit),
                                                    obj=energy_in))
        return warnings
Exemple #22
0
    def getDistribution(self, energy, energies, numberOfGammas, zeroTotal):

        energy_eV = 1e6 * energy
        if (self.multiplicity.domainMin() <= energy <=
                self.multiplicity.domainMax()):
            domainMin_eV, domainMax_eV = self.energyForm.domain()
            dE = energy_eV - domainMin_eV
            if (dE < 0):
                if (abs(dE) < 1e-15 * energy_eV):
                    energy_eV = domainMin_eV
                else:
                    return (None)
            dE = domainMax_eV - energy_eV
            if (dE < 0):
                if (abs(dE) < 1e-15 * energy_eV):
                    energy_eV = domainMin_eV
                else:
                    return (None)

            energyForm = self.energyForm
            if (isinstance(energyForm, (energyModule.piecewise, ))):
                for region in energyForm:
                    if (energy_eV < region.domainMax()): break
                energyForm = region
            energyForm = energyForm.evaluate(energy_eV, epsilon=3 * energyEps)
            energyForm = energyForm.toPointwise_withLinearXYs(
                accuracy=1e-4, lowerEps=energyEps, upperEps=energyEps)
            lowerEps = energyEps
            if (energyForm.domainMin() == 0): lowerEps = 0
            energyForm = energyForm.scaleOffsetXAndY(
                xScale=eV2MeV, yScale=1 / eV2MeV).dullEdges(lowerEps=lowerEps,
                                                            upperEps=energyEps)
            energyForm = XYsModule.XYs(energyForm)
            multiplicity = getMultiplicityForDistributionSum(
                self, energy, energies, numberOfGammas, zeroTotal)
            distribution = multiplicity * energyForm
            return (distribution)
        else:
            return (None)
Exemple #23
0
def addContinuumSpectrum(decayModes, RTYP_key, decayParticleIndex, regions,
                         covariance):

    decayParticleID = decayParticles[decayParticleIndex]
    if (decayParticleID is None):
        raise Exception('decayParticleID is None, what is to be done?')

    decayParticleLabel = STYPProduct[decayParticleIndex]
    spectra = decayModes[RTYP_key].spectra
    if (decayParticleLabel not in spectra):
        spectrum = spectrumModule.spectrum(decayParticleLabel, decayParticleID)
        spectra.add(spectrum)
    else:
        spectrum = spectra[decayParticleLabel]

    if (len(regions) == 1):
        data = XYsModule.XYs1d(
            regions[0], axes=spectrumModule.continuum.defaultAxes(energyUnit))
    else:
        print("len( regions ) > 1")
        return
    continuum = spectrumModule.continuum(data)
    spectrum.append(continuum)
Exemple #24
0
def get_ENDF_flux(file, mat, mf, mt):
    import fudge.legacy.converting.ENDFToGND.endfFileToGNDMisc as endfFileToGNDMiscModule
    import xData.axes as axesModule
    import xData.XYs as XYsModule
    # Grab the data corresponding to the spectrum
    MF3Data = [
        line.strip('\r\n') for line in open(file).readlines()
        if int(line[67:70]) == int(mat) and int(line[70:72]) == int(mf)
        and int(line[72:75]) == int(mt)
    ]
    # Define the axes
    spectrumAxes = axesModule.axes(rank=2)
    spectrumAxes[0] = axesModule.axis('spectrum', 0, '1/eV')
    spectrumAxes[1] = axesModule.axis('energy_in', 1, 'eV')
    # Now make the spectrum as an XYs1d
    dataLine, TAB1, spectrumRegions = endfFileToGNDMiscModule.getTAB1Regions(
        1,
        MF3Data,
        allowInterpolation6=True,
        logFile=None,  #info.logs,
        axes=spectrumAxes,
        cls=XYsModule.XYs1d)
    if (len(spectrumRegions) == 1):  # Store as XYs1d.
        spectrumForm = XYsModule.XYs1d(
            data=spectrumRegions[0],
            label=None,
            axes=spectrumAxes,
            interpolation=spectrumRegions[0].interpolation)
    else:
        raise NotImplementedError(
            "Fluxes with multiple regions for %s/%s/%s/%s" %
            (file, mat, mf, mt))
        spectrumForm = crossSectionModule.regions1d(label=None,
                                                    axes=spectrumAxes)
        for region in spectrumRegions:
            if (len(region) > 1): spectrumForm.append(region)
    return (spectrumForm)
Exemple #25
0
def toENDL(coherentElastic,
           energyMin_MeV,
           energyMax_MeV,
           temperature_MeV,
           accuracy=0.001,
           epsilon=1e-6):

    S_table = coherentElastic.S_table
    gridded2d = S_table.gridded2d

    array = gridded2d.array.constructArray()

    energyGrid = gridded2d.axes[1].copy([])

    temperatureGrid = gridded2d.axes[2].copy([])
    temperatureGrid.convertToUnit('MeV/k')
    for index2, temperature2 in enumerate(temperatureGrid.values):
        if (temperature2 >= temperature_MeV): break
    if (temperature_MeV > temperature2):
        SofE = XYsModule.XYs1d((energyGrid.values, array[-1]),
                               dataForm='XsAndYs',
                               interpolation=energyGrid.interpolation)
    elif ((index2 == 0) or (temperature2 == temperature_MeV)):
        SofE = XYsModule.XYs1d((energyGrid.values, array[index2]),
                               dataForm='XsAndYs',
                               interpolation=energyGrid.interpolation)
    else:
        index1 = index2 - 1
        temperature1 = temperatureGrid.values[index1]
        fraction = (temperature_MeV - temperature1) / (temperature2 -
                                                       temperature1)

        SofE1 = XYsModule.XYs1d((energyGrid.values, array[index1]),
                                dataForm='XsAndYs',
                                interpolation=energyGrid.interpolation)
        SofE2 = XYsModule.XYs1d((energyGrid.values, array[index2]),
                                dataForm='XsAndYs',
                                interpolation=energyGrid.interpolation)
        SofE = (1 - fraction) * SofE1 + fraction * SofE2

    axes = axesModule.axes()
    axes[0].label = gridded2d.axes[0].label
    axes[0].unit = gridded2d.axes[0].unit
    axes[1].label = energyGrid.label
    axes[1].unit = energyGrid.unit
    SofE.axes = axes
    SofE.convertUnits({"eV": "MeV"})

    _SofE = SofE
    SofE = []
    for energy, S2 in _SofE:
        if (energy > energyMax_MeV): break
        SofE.append([energy, S2])
    if ((SofE[-1][0] < energyMax_MeV) and (SofE[-1][0] < _SofE[-1][0])):
        eMax = _SofE[-1][0]
        if (energyMax_MeV < eMax): eMax = energyMax_MeV
        SofE.append([eMax, SofE[-1][1]])

    S1 = 0
    I0 = []
    I1 = []
    n_minus1 = len(SofE) - 1
    for index, energyS in enumerate(SofE):
        energy, S2 = energyS

        energy1 = (1 - epsilon) * energy
        if (index == 0):
            S1 = S2
            energy1 = energy

        energy2 = (1 + epsilon) * energy
        if (index == n_minus1): energy2 = energy

        if (energy >= energyMax_MeV):
            energy = energyMax_MeV
            energy2 = energyMax_MeV
        if (energy2 > energyMax_MeV):
            energy2 = energyMax_MeV

        I0.append([energy1, S1 / energy])
        if (energy != energy1): I0.append([energy2, S2 / energy])

        PofMu = calculatePofMu(energy1, index, SofE, epsilon)
        if (len(PofMu) > 0): I1.append([energy1, PofMu])
        if (energy != energy1):
            PofMu = calculatePofMu(energy2, index + 1, SofE, epsilon)
            if (len(PofMu) > 0): I1.append([energy2, PofMu])

        S1 = S2
        if (energy == energyMax_MeV): break

    accuracy = min(0.1, max(1e-5, accuracy))
    I0Fine = [I0.pop(0)]
    x1, y1 = I0Fine[0]
    for x2, y2 in I0:
        if ((x2 - x1) > (2 * epsilon * x1)):
            bisectionTest(I0Fine, x1, y1, x2, y2, accuracy)
        I0Fine.append([x2, y2])
        x1, y1 = x2, y2

    return (I0Fine, I1, None)
Exemple #26
0
    def calculate_a( self, energy_in, energy_out_cmMin, energy_out_cmMax, accuracy = 1e-6 ) :

        from fudge.core.math import fudgemath
        from fudge.particles import nuclear

        def getParticleData( particle ) :

            Z, A, suffix, ZA = particle.getZ_A_SuffixAndZA( )
            return( particle.name, Z, max( 0, A - Z ), A, particle.getMass( 'MeV/c**2' ) )

        energyFactor = PQU.PQU( 1, 'MeV' ).getValueAs( self.fSubform.data.axes[-1].unit )
        projectile = self.findAttributeInAncestry( 'projectile' )
        target = self.findAttributeInAncestry( 'target' )
        product = self.findClassInAncestry( fudge.gnd.product.product ).particle
        name_a, Z_a, N_a, A_a, AWRa = getParticleData( projectile )
        name_A, Z_A, N_A, A_A, AWRA = getParticleData( target )
        name_b, Z_b, N_b, A_b, AWRb = getParticleData( product )
        Z_C, N_C = Z_a + Z_A, N_a + N_A
        if( N_A == 0 ) : N_C = 0
        Z_B, N_B = Z_C - Z_b, max( 0, N_C - N_b )
        A_B = Z_B + N_B
        if( N_B == 0 ) : A_B = 0
        particles = self.findClassInAncestry( fudge.gnd.reactionSuite.reactionSuite ).particles
        residual = particles.getParticle( nuclear.nucleusNameFromZA( 1000 * Z_B + A_B ) )
        AWRB = residual.getMass( 'MeV/c**2' )
        Ma, Ia = self.KalbachMann_a_parameters[name_a]['M'], self.KalbachMann_a_parameters[name_a]['I']
        mb, Ib = self.KalbachMann_a_parameters[name_b]['m'], self.KalbachMann_a_parameters[name_b]['I']
        Sa, Sb = energyFactor * self.calculate_S_ab_MeV( Z_A, N_A, Z_C, N_C, Ia ), energyFactor * self.calculate_S_ab_MeV( Z_B, N_B, Z_C, N_C, Ib )

        C1, C2, C3 = 0.04 / energyFactor, 1.8e-6 / energyFactor**3, 6.7e-7 / energyFactor**4

        ea = energy_in * AWRA / ( AWRa + AWRA ) + Sa

        R1, R3 = 130 * energyFactor, 41 * energyFactor                        # MeV to self's energy units.
        if( ea < R1 ) : R1 = ea
        if( ea < R3 ) : R3 = ea

        def calculate_a2( energy_out_cm ) :

            eb = energy_out_cm * ( AWRb + AWRB ) / AWRB + Sb
            X1, X3 = R1 * eb / ea, R3 * eb / ea
            return( X1 * ( C1 + C2 * X1 * X1 ) + C3 * Ma * mb * X3**4 )

        class thicken_a :

            def __init__( self, calculate_a2, relativeTolerance, absoluteTolerance ) :

                self.calculate_a2 = calculate_a2
                self.relativeTolerance = relativeTolerance
                self.absoluteTolerance = absoluteTolerance

            def evaluateAtX( self, x ) :

                return( self.calculate_a2( x ) )

        a = [ [ energy_out_cmMin, calculate_a2( energy_out_cmMin ) ], [ energy_out_cmMax, calculate_a2( energy_out_cmMax ) ] ]
        a = fudgemath.thickenXYList( a, thicken_a( calculate_a2, accuracy, 1e-10 ) )

        axes = axesModule.axes( )
        axes[0] = axesModule.axis( 'a', 0, '' )
        axes[1] = self.fSubform.data.axes[1].copy( )
        return( XYsModule.XYs1d( data = a, axes = axes, accuracy = accuracy ) )
Exemple #27
0
def toACE(self, fileName, evaluationId, temperature, productData,
          addAnnotation):

    massUnit = 'eV/c**2'
    projectile, target = self.projectile, self.target
    targetZ, targetA, targetSuffix, targetZA = target.getZ_A_SuffixAndZA()
    neutronMass = projectile.getMass(massUnit)
    targetMass = target.getMass(massUnit)
    target2NeutronMass = targetMass / neutronMass

    if (not (isinstance(temperature, PQU.PQU))):
        temperature = PQU.PQU(temperature)

    if (temperature.isTemperature()):
        temperature_MeV = temperature.getValueAs('MeV / k')
        temperature_K = temperature.getValueAs('K')
    else:
        temperature_MeV = temperature.getValueAs('MeV')
        temperature_K = temperature.getValueAs('k * K')

    processingTime = time.localtime()
    strRecords = [
        "%6d.%.2dc%12.7f %11.5E %.2d/%.2d/%.2d" %
        (targetZA, evaluationId, target2NeutronMass, temperature_MeV,
         processingTime[1], processingTime[2], processingTime[0])
    ]

    nonFissionEnergyDependentNeutronMultiplicities = []
    nonFissionEnergyDependentNeutronMultiplicitiesIndex = 100

    MAT = endf_endl.ZAAndMATFromParticleName(target.name)[1]
    MAT_ID = '  mat %d' % MAT
    HK = '%2d-%s at %.1fK from %s-%s Fudge.toACE' % \
        ( targetZ, target.name, temperature_K, self.styles['evaluated'].attributes['library'], self.styles['evaluated'].attributes['version'] )
    HK = "%-70s" % HK[:70]
    strRecords.append(HK + MAT_ID)
    for i in xrange(4):
        strRecords.append(
            '      0   0.000000      0   0.000000      0   0.000000      0   0.000000'
        )

    NXS = 16 * [0]
    JXS = 32 * [0]
    MRT, NU_prompt, NU_total, LQR, TYP, SigData, neutronAngular, neutronEnergies = [], None, None, [], [], {}, [], []
    NXS[2 - 1] = targetZA

    for MT, MTData in productData:
        if (MT == 2):  # Elastic (MT = 2) must always be present in ACE file.
            EMin = MTData['ESZ'].domainMin(unitTo='MeV')
            break
    totalXSec = XYs.XYs(
        axes.defaultAxes(labelsUnits={
            0: ('', 'MeV'),
            1: ('', 'b')
        }), [], 1e-3)
    absorptionXSec = XYs.XYs(
        axes.defaultAxes(labelsUnits={
            0: ('', 'MeV'),
            1: ('', 'b')
        }), [], 1e-3)
    sortedMTs = sorted([[MTData[0], i1]
                        for i1, MTData in enumerate(productData)
                        ])  # Sort MTs like NJOY.
    for MT, i1 in sortedMTs:
        MT_, MTData = productData[i1]
        XSec = MTData['ESZ']
        XSec = XSec.convertAxisToUnit(0, 'MeV')
        XSec = XSec.convertAxisToUnit(1, 'b')
        neutronDatas = MTData['n']
        multiplicity = 0
        if (MT == 2):
            elasticXSec = XSec
            if (len(neutronDatas) > 1):
                raise Exception(
                    'Only one type of neutron data is support for the elastic reaction.'
                )
            if (len(neutronDatas) > 0):
                neutronAngular.append((MT, neutronDatas[0]['angularData']))
        else:
            MRT.append(MT)
            LQR.append(MTData['Q'])
            if (XSec[0][0] != 0):
                if (XSec[0][0] > EMin): XSec = XSec.dullEdges(lowerEps=1e-8)
            SigData[MT] = XSec
            totalXSec = totalXSec + XSec
            if (len(neutronDatas) == 0):
                absorptionXSec = absorptionXSec + XSec
                neutronMultiplicity = 0
            else:
                NXS[5 - 1] += 1
                product = neutronDatas[0]['product']
                frame = neutronDatas[0]['frame']
                angularData = neutronDatas[0]['angularData']
                energyData = neutronDatas[0]['energyData']
                if (MTData['isFission']):
                    neutronMultiplicity = 19
                    totalPresent = False
                    for neutronData in neutronDatas:
                        product = neutronData['product']
                        if ((product.attributes['emissionMode']
                             == tokens.promptToken) or
                            (product.attributes['emissionMode'] == 'total')):
                            totalPresent = product.attributes[
                                'emissionMode'] == 'total'
                            NU_prompt = neutronData['multiplicity']
                            break
                    if (NU_prompt is None):
                        raise Exception('Missing prompt neutron')
                    if (len(neutronDatas) > 1):
                        if (totalPresent):
                            raise Exception(
                                'Total nu_bar present and delayed neutron data.'
                            )
                        NU_total = NU_prompt
                        for neutronData in neutronDatas:
                            product = neutronData['product']
                            if (product.attributes['emissionMode'] == 'delayed'
                                ):
                                NU_delayed = neutronData['multiplicity']
                                if (NU_delayed.domainMax() <
                                        NU_total.domainMax()):
                                    NU_delayed = NU_delayed.dullEdges(
                                        upperEps=1e-8)
                                NU_total = NU_total + NU_delayed
                else:
                    if (len(neutronDatas) == 1):
                        neutronMultiplicity = neutronDatas[0]['multiplicity']
                    else:
                        neutronMultiplicity, angularData, energyData = specialMF6.neutrons(
                            neutronDatas)
                    if (not (isinstance(neutronMultiplicity, int))):
                        nonFissionEnergyDependentNeutronMultiplicitiesIndex += 1
                        nonFissionEnergyDependentNeutronMultiplicities.append([
                            MT,
                            nonFissionEnergyDependentNeutronMultiplicitiesIndex,
                            neutronMultiplicity
                        ])
                        neutronMultiplicity = nonFissionEnergyDependentNeutronMultiplicitiesIndex

                    if (frame == axes.centerOfMassToken):
                        neutronMultiplicity *= -1  # Negative for COM frame.
                    if (energyData is None):
                        if (50 <= MT <= 91):
                            energyData = n_nPrimeEnergyData(
                                MT, target2NeutronMass, MTData['Q'])
                        else:
                            raise 'hell: but first implement energy for MT =' % MT
                    else:
                        if (isinstance(energyData,
                                       distributions.energy.NBodyPhaseSpace)):
                            angularData = None
                neutronAngular.append((MT, angularData))
                neutronEnergies.append(
                    [MT, XSec.xMin(), XSec.xMax(), energyData])
            TYP.append(neutronMultiplicity)
    totalXSec = elasticXSec + totalXSec
    annotates, XSS, energyGrid, totalSigma = [], [], [], []
    for E, sigma in totalXSec:
        energyGrid.append(E)
        totalSigma.append(sigma)

# 1) Add the ESZ block.
    NXS[3 - 1] = len(energyGrid)
    updateXSSInfo('energyGrid', annotates, XSS, energyGrid)
    updateXSSInfo('totalSigma', annotates, XSS, totalSigma)
    if (len(absorptionXSec) == 0):
        updateXSSInfo('absorption cross section', annotates, XSS,
                      len(energyGrid) * [0.])
    else:
        updateXSSInfo('absorption cross section', annotates, XSS,
                      mapEnergyToTotal(totalXSec, absorptionXSec))
    updateXSSInfo('elastic cross section', annotates, XSS,
                  mapEnergyToTotal(totalXSec, elasticXSec))
    averageHeating = len(energyGrid) * [0.]
    updateXSSInfo('average heating', annotates, XSS, averageHeating)

    # 2) Add the NU block.
    if (NU_prompt is not None):
        JXS[2 - 1] = len(XSS) + 1
        NU_prompt = NU_prompt.toACE()
        if (NU_total is not None): NU_prompt.insert(0, -len(NU_prompt))
        updateXSSInfo('NU', annotates, XSS, NU_prompt)
        if (NU_total is not None):
            NU_total = NU_total.toACE()
            updateXSSInfo('NU(total)', annotates, XSS, NU_total)

# 3) Add the MRT block.
    NXS[4 - 1] = len(MRT)
    JXS[3 - 1] = len(XSS) + 1
    updateXSSInfo('MRT', annotates, XSS, MRT)

    # 4) Add the LQR block.
    JXS[4 - 1] = len(XSS) + 1
    updateXSSInfo('LQR', annotates, XSS, LQR)

    # 5) Add the TYP block.
    JXS[5 - 1] = len(XSS) + 1
    updateXSSInfo('TYP', annotates, XSS, TYP)

    # 6 and 7) Add the LSIG and SIG blocks.
    SIG = []
    for MT, MTData in productData:
        if (MT not in [2]): addSigData(MT, SIG, energyGrid, SigData[MT])
    JXS[6 - 1] = len(XSS) + 1
    LSIG = [1]
    for MT, firstNonZero, reactionSIG in SIG[:-1]:
        LSIG.append(LSIG[-1] + len(reactionSIG) + 2)
    updateXSSInfo('LSIG', annotates, XSS, LSIG)
    JXS[7 - 1] = len(XSS) + 1
    for MT, firstNonZero, reactionSIG in SIG:
        reactionSIG_ = [firstNonZero + 1, len(reactionSIG)] + reactionSIG
        updateXSSInfo('SIG(MT=%s)' % MT, annotates, XSS, reactionSIG_)

# 8 and 9) Add the LAND and AND blocks.
    LAND, MT_AND, length = [], [], 0
    for MT, angular in neutronAngular:
        if (angular is None):
            LAND.append(-1)
        elif (angular.isIsotropic()):
            LAND.append(0)
        elif (isinstance(angular, (distributions.angular.linear,
                                   angularEnergy.angularFor_angularEnergy))):
            LAND.append(length + 1)
            length += 2 * len(angular) + 1
            energies_in = [len(angular)]
            LCs, Ps = [], []
            for xys in angular:
                energy_in = PQU.PQU(
                    xys.value, angular.axes[0].getUnit()).getValueAs('MeV')
                energies_in.append(energy_in)
                LCs.append(-length - 1)
                xys = xys.normalize()
                mus, pdf = [], []
                for x, y in xys:
                    mus.append(x)
                    pdf.append(y)
                cdf = xys.runningIntegral()
                cdf[-1] = 1.  # Make sure last point is really 1.
                Ps += [2, len(mus)] + mus + pdf + cdf
                length += 3 * len(xys) + 2
            MT_AND.append((MT, energies_in + LCs + Ps))
        else:
            raise Exception(
                'Unsupport neutron angular distribution type = %s' %
                type(angular))
    JXS[8 - 1] = len(XSS) + 1
    updateXSSInfo('LAND', annotates, XSS, LAND)
    JXS[9 - 1] = len(XSS) + 1
    for MT, AND in MT_AND:
        updateXSSInfo('AND(MT=%s)' % MT, annotates, XSS, AND)

    # 10 and 11) Add the LDLW and DLW blocks.
    LDLW, MT_DLW = processEnergyData(massUnit, neutronMass, neutronEnergies)
    JXS[10 - 1] = len(XSS) + 1
    updateXSSInfo('LDLW', annotates, XSS, LDLW)
    JXS[11 - 1] = len(XSS) + 1
    for MT, DLW in MT_DLW:
        updateXSSInfo('DLW(MT=%s)' % MT, annotates, XSS, DLW)

    # Now fixup the TYP data whose abs( value ) is greater than 100.
    for MT, index, multiplicity in nonFissionEnergyDependentNeutronMultiplicities:
        i1, found = JXS[5 - 1], False
        for i2 in range(NXS[4 - 1]):
            if (abs(XSS[i1 + i2 - 1]) == index):
                n_multiplicity = multiplicity.toACE()
                LNU, n_multiplicity = n_multiplicity[0], n_multiplicity[1:]
                if (LNU != 2):
                    raise Exception(
                        'Only tabular neutron multiplicity is allowed, not LNU = %d'
                        % LNU)
                offset = len(XSS) - JXS[11 - 1] + 101 + 1
                if (XSS[i1 + i2 - 1] < 0): offset *= -1
                XSS[i1 + i2 - 1] = offset
                updateXSSInfo('Neutron Yields(MT=%s)' % MT, annotates, XSS,
                              n_multiplicity)
                found = True
                break
        if (not (found)):
            raise Exception(
                'Neutron multiplicity for index %s not found in TYP table' %
                index)


# Time to wrap it all up.
    NXS[1 - 1] = len(XSS)
    JXS[1 - 1] = 1
    JXS[22 - 1] = len(
        XSS) + 1  # Location of the last word of XSS (i.e., its length).

    strRecords += intArrayToRecords(NXS)
    strRecords += intArrayToRecords(JXS)
    strRecords += XSSToStrings(annotates, XSS, addAnnotation)

    strRecords.append('')
    fOut = open(fileName, 'w')
    fOut.write('\n'.join(strRecords))
    fOut.close()
Exemple #28
0
def plotTests(tests=11 * [False]):

    from fudge import fudgeParameters
    fudgeParameters.VerboseMode = 0
    from fudge.legacy.endl.endlProject import endlProject
    from fudge.legacy.endl.endl3dmathClasses import endl3dmath
    from fudge import __path__
    from xData import axes as axesModule
    from xData import XYs as XYsModule
    from xData import multiD_XYs as multiD_XYsModule

    testData = '''
        #  Authors:   T.S.Suzuki, Y.Nagai, T.Shima, T.Kikuchi, H.Sato, T.Kii, M.Igashira
        #  Title:     First Measurement Of A P(N,Gamma)D Reaction Cross Section Between 10 And 80 Kev
        #  Year:      1995
        #  Institute: Tokyo Inst.of Technology, Tokyo
        #  Reference: Astrophysical Journal 439, (L), 59 (1995)
        #  Subent:    22310002
        #  Reaction:  Cross section for 1H(n,gamma)2H 
        # Note: the d(Energy) errorbars are fake and are used for plot testing
        #   Energy        Data          d(Energy)     d(Data)       
        #   MeV           barns         MeV           barns         
            0.02          0.000353      0.001         2.6e-05       
            0.02          0.000329      0.001         2.6e-05       
            0.02          0.000287      0.0           2.2e-05       
            0.02          0.000304      0.0           1.8e-05       
            0.04          0.00023       0.001         1.5e-05       
            0.04          0.000198      0.001         1.2e-05      
            0.04          0.000177      0.0015        1e-05         
            0.04          0.000207      0.0           1.3e-05       
            0.064         0.000156      0.0           1.1e-05       
            0.064         0.00015       0.0           7e-06         
            0.064         0.000158      0.0           1.1e-05       
            0.064         0.00014       0.0           9e-06
    '''

    e = endlProject(__path__[0] + "/legacy/endl/test/testdb")
    za = e.readZA(1001)
    za.read()
    xAxis = AxisSettings(isLog=True,
                         label='$E_n$',
                         axisMin=0.5e-2,
                         axisMax=1.5e-1,
                         gridOn=True,
                         autoscale=False,
                         unit='MeV')
    yAxis = AxisSettings(isLog=True,
                         label='$\sigma(E_n)$',
                         gridOn=True,
                         unit='b')
    d = []
    u = []
    for line in testData.split('\n'):
        if line.strip().startswith('#'): continue
        sline = map(float, line.split())
        if len(sline) != 0:
            d.append(sline[0:2])
            u.append(sline[2:4])

    xyAxes = axesModule.axes(labelsUnits={
        1: (xAxis.label, xAxis.unit),
        0: (yAxis.label, yAxis.unit)
    })

    # Simple test, here we make a plot of one set

    if tests[0]:
        xSec = za.findData(I=0, C=46)
        makePlot2d([xSec],
                   xAxisSettings=xAxis,
                   yAxisSettings=yAxis,
                   title='$^1$H$(n,\gamma)$ Cross Section',
                   outFile=None)
        xys = XYsModule.XYs(xSec.data, axes=xyAxes, accuracy=1e-3)
        makePlot2d((xys),
                   xAxisSettings=xAxis,
                   yAxisSettings=yAxis,
                   title='$^1$H$(n,\gamma)$ Cross Section',
                   outFile=None)
        dataset = DataSet2d(xys, xUnit=xAxis.unit, yUnit=yAxis.unit)
        dataset.convertUnits('eV', 'mb')
        makePlot2d((dataset),
                   xAxisSettings=xAxis,
                   yAxisSettings=yAxis,
                   title='$^1$H$(n,\gamma)$ Cross Section',
                   outFile=None)

    # Plot all the cross section data in the fudge2 test library, but unthemed!
    if tests[1]:
        makePlot2d(za.findDatas(I=0), outFile=None)

    # Plot all the cross section data in the fudge2 test library
    if tests[2]:
        xSecs = za.findDatas(I=0)
        makePlot2d(xSecs,
                   xAxisSettings=xAxis,
                   yAxisSettings=yAxis,
                   title='$^1$H$(n,*)$ Cross Sections',
                   outFile=None)
        xySecs = [
            XYsModule.XYs(xSec.data, axes=xyAxes, accuracy=1e-3)
            for xSec in xSecs
        ]
        xySecs = (xySecs[0], xySecs[1], xySecs[2])
        makePlot2d(xySecs,
                   xAxisSettings=xAxis,
                   yAxisSettings=yAxis,
                   title='$^1$H$(n,*)$ Cross Sections',
                   outFile=None)

    # Fancy test, here we make a plot of one dataset (the testData above)
    if tests[3]:
        endfData = za.findData(I=0,
                               C=46)  #.slicex(domainMin=1e-2,domainMax=1e-1)
        endfUnc = 0.1 * endfData  # 10% error bars
        makePlot2d( [ \
                DataSet2d( data = endfData, uncertainty = endfUnc, legend = 'ENDF/B-VII.0', color='g', lineStyle = '-' ),
                DataSet2d( data = d, uncertainty = u, legend = 'T.S.Suzuki, et al. (1995) EXFOR entry # 22310002', color='g', symbol = 'o' ),
            ], xAxisSettings = xAxis, yAxisSettings = yAxis, title = '$^1$H$(n,\gamma)$ Cross Section', legendOn = True, outFile = None )

    # Contour test
    if tests[
            4]:  # Contour plots are meaningful if there is only one dataset plotted, how do we enforce this?
        endfData = za.findData(yo=1, I=1, C=10)
        EAxis = AxisSettings(isLog=False,
                             label='$E_n$ (MeV)',
                             axisMin=1.0,
                             axisMax=20.0,
                             gridOn=True,
                             autoscale=False,
                             unit='MeV')
        muAxis = AxisSettings(isLog=False,
                              label='$\mu$ = cos( $\\theta$ )',
                              axisMin=-1.0,
                              axisMax=1.0,
                              autoscale=False,
                              gridOn=True)
        makePlot2dContour(DataSet3d(data=endfData,
                                    legend='ENDF/B-VII.0',
                                    xUnit=EAxis.unit,
                                    yUnit=muAxis.unit),
                          xAxisSettings=EAxis,
                          yAxisSettings=muAxis,
                          title='$^1$H$(n,el)$ Angular Distribution',
                          outFile=None)
        w_xys = multiD_XYsModule.multiD_XYs(
            axes=axesModule.axes(rank=3, labelsUnits={2: ('$E_n$', 'MeV')}))
        for w, xy in endfData.data:
            w_xys.append(
                XYsModule.XYs(xy,
                              axes=axesModule.axes(),
                              accuracy=1e-3,
                              value=w))
        dataset = DataSet3d(data=w_xys, legend='ENDF/B-VII.0')
        dataset.convertUnits('eV', None, None)
        makePlot2dContour(dataset,
                          xAxisSettings=EAxis,
                          yAxisSettings=muAxis,
                          title='$^1$H$(n,el)$ Angular Distribution',
                          outFile=None)

    # Slice tests
    if (tests[5] or tests[6] or tests[7] or tests[8] or tests[9]):
        endfDataI0 = za.findData(yo=0, I=0,
                                 C=10).slicex(1.0, 20.0)  # simplify the plot
        endfDataI1 = za.findData(yo=1, I=1, C=10)
        Es = [p[0] for p in endfDataI0.data]  # in [MeV]
        mus = []  # in [mu]
        for t in endfDataI1.data:
            mus += [p[0] for p in t[1]]
        mus = sorted(uniquify(mus))
        table = []
        for E in Es:
            muDist = []
            for mu in mus:
                muDist.append(
                    [mu,
                     endfDataI0.getValue(E) * endfDataI1.getValue(E, mu)])
            table.append([E, muDist])
        endfDataCombined = endl3dmath(data=table)
        EAxis = AxisSettings(isLog=True,
                             label='$E_n$ (MeV)',
                             axisMin=1.0,
                             axisMax=20.0,
                             gridOn=True,
                             autoscale=False)
        muAxis = AxisSettings(isLog=False,
                              label='$\mu = \cos{( \\theta )}$',
                              axisMin=-1.0,
                              axisMax=1.0,
                              autoscale=False,
                              gridOn=True)
        zAxis = AxisSettings(isLog=True,
                             label='$d\sigma(E)/d\mu$ (b)',
                             axisMin=0.0,
                             axisMax=5.0,
                             autoscale=False,
                             gridOn=True)

        # unthemed slice tests
        if tests[5]:
            makePlot2dSlice(
                endfDataCombined,
                xyAxisSettings=EAxis,
                zAxisSettings=zAxis,
                sliceXCoords=None,
                sliceYCoords=[-1.0, -0.75, -0.5, -.25, 0.0, .25, .5, .75, 1.0],
                title='',
                outFile=None)
            dataSet3d = DataSet3d(data=endfDataCombined, legend='ENDF/B-VII.0')
            makePlot2dSlice(
                dataSet3d.getW_XYs(),
                xyAxisSettings=EAxis,
                zAxisSettings=zAxis,
                sliceXCoords=None,
                sliceYCoords=[-1.0, -0.75, -0.5, -.25, 0.0, .25, .5, .75, 1.0],
                title='',
                outFile=None)
        if tests[6]:
            makePlot2dSlice(endfDataCombined,
                            xyAxisSettings=muAxis,
                            zAxisSettings=zAxis,
                            sliceXCoords=[1.0, 5.0, 10.0, 15.0, 20.0],
                            sliceYCoords=None,
                            title='',
                            outFile=None)

        # themed slice test and contour test
        if tests[7]:
            makePlot2dContour(DataSet3d(data=endfDataCombined,
                                        legend='ENDF/B-VII.0'),
                              xAxisSettings=EAxis,
                              yAxisSettings=muAxis,
                              numContours=10,
                              title='$d\sigma(E)/d\mu$ for $^1$H$(n,el)$',
                              outFile=None)
        if tests[8]:
            makePlot2dSlice(
                DataSet3d(data=endfDataCombined, legend='ENDF/B-VII.0'),
                xyAxisSettings=EAxis,
                zAxisSettings=zAxis,
                sliceXCoords=None,
                sliceYCoords=[-1.0, -0.75, -0.5, -.25, 0.0, .25, .5, .75, 1.0],
                title='',
                outFile=None)

        # themed slice test, with test 2d experimental data
        if tests[9]:
            makePlot2dSlice( [ \
                DataSet3d( data = endfDataCombined, legend = 'ENDF/B-VII.0' ), \
                DataSet2d( data = d, uncertainty = u, legend = 'T.S.Suzuki, et al. (1995) EXFOR entry # 22310002', color='g', symbol = 'o' ),\
            ], xyAxisSettings = muAxis, zAxisSettings = zAxis, sliceXCoords = [ 1.0, 5.0, 10.0, 15.0, 20.0 ], sliceYCoords = None, sliceUnits = 'MeV', title = 'Slice test', outFile = None )
Exemple #29
0
def primaryGammaAngularData( style, tempInfo, crossSection, energyData, angularData, multiplicity = 1, comment = None ) :
    """
    Currently, only isotropic (i.e., l = 0) data are returned. That is, lMax and angularData are ignored. massRatio is the
    target mass divide by the sum of the projectile and target masses.

    This function perform the integration 

        TM = \int_g dE \int_h dE' S(E) M(E) f(E) P(E -> E') / \int_g dE f(E)

    where \int_g is the integral of E from E_i to E_{i+1}, \int_g is the integral of E' from E'_j to E'_{j+1}, S(E) is the cross section,
    M(E) is the products multiplicity, f(E) is the flux weighting and P(E -> E') is the probability for a projectile of energy E producing
    a primary gamma of energy E' for binding energy bindingEnergy. This function assumes that M(E) is a constant. For primary gamma's captured
    into binding energy bindingEnergy P(E -> E') = deltaFunction( E' - ( bindingEnergy + massRatio E ) ) where massRatio = mt / ( mp + mt ),
    mp is the projectile's mass and mt is the target's mass. Note, this formula is from the ENDF manual which ignores the recoil of the residual
    nucleus.
    """

    reactionSuite = tempInfo['reactionSuite']
    projectileName = reactionSuite.projectile
    projectileGroupBoundaries = style.transportables[projectileName].group.boundaries
    productName = tempInfo['productName']
    productGroupBoundaries = style.transportables[productName].group.boundaries
    flux0 = style.flux.getFluxAtLegendreOrder( 0 )
    groupedFlux = tempInfo['groupedFlux']

    bindingEnergy = energyData.value * energyData.axes[1].unitConversionFactor( tempInfo['incidentEnergyUnit'] )
    massRatio = energyData.massRatio

    nProj = len( projectileGroupBoundaries.values ) - 1
    nProd = len( productGroupBoundaries.values ) - 1
    TM_1, TM_E = {}, {}
    for i1 in range( nProj ) :
        TM_1[i1] = {}
        TM_E[i1] = {}
        for i2 in range( nProd ) :
            TM_1[i1][i2] = [ 0. ]
            TM_E[i1][i2] = [ 0. ]
    Eg2 = bindingEnergy + massRatio * projectileGroupBoundaries.values[0]
    for indexEo, Eo in enumerate( productGroupBoundaries.values ) :
        if( Eg2 <= Eo ) : break
    indexEo = min( max( indexEo - 1, 0 ), nProd - 1 )

    EMin, EMax = crossSection.domainMin, crossSection.domainMax
    axes = axesModule.axes( labelsUnits = { 0 : ( 'energy_out', tempInfo['incidentEnergyUnit'] ), 
                                            1 : ( crossSection.axes[1].label, crossSection.axes[1].unit ) } )
    Egp = XYsModule.XYs1d( data = [ [ EMin, bindingEnergy + massRatio * EMin ], [ EMax, bindingEnergy + massRatio * EMax ] ], axes = axes )

    for indexEi in range( nProj ) :
        Ei2 = projectileGroupBoundaries.values[indexEi + 1]
        Eg2 = bindingEnergy + massRatio * Ei2
        EiMin = projectileGroupBoundaries.values[indexEi]
        while( True ) :
            incrementIndexEo, EiMax = 0, Ei2
            if( indexEo < ( nProd - 1 ) ) :
                if( Eg2 > productGroupBoundaries.values[indexEo + 1] ) :
                    incrementIndexEo = 1
                    EiMax = ( productGroupBoundaries.values[indexEo + 1] - bindingEnergy ) / massRatio
            TM_1[indexEi][indexEo][0] = float( crossSection.integrateTwoFunctions( flux0, 
                    domainMin = EiMin, domainMax = EiMax ) / groupedFlux[indexEi] )
            TM_E[indexEi][indexEo][0] = float( crossSection.integrateThreeFunctions( flux0, Egp, 
                    domainMin = EiMin, domainMax = EiMax ) / groupedFlux[indexEi] )
            if( incrementIndexEo == 0 ) : break
            EiMin = EiMax
            if( indexEo < ( nProd - 1 ) ) : indexEo += 1
    return( TM_1, TM_E )
Exemple #30
0
    def group( self, groupBoundaries = ( None, None ), groupUnit = ( None, None ) ):
        '''
        Group the matrix in self

        :param groupBoundaries: a 2 element list containing the group boundaries for the rows 
                                and columns (respectively) of the covariance to be regrouped
                                rows go in the first element, columns in the second
        :param groupUnit: a 2 element list containing the units in which group boundaries are 
                          specified for the rows and columns (respectively) of the covariance 
                          to be regrouped

        :returns: the regrouped matrix (an xData.array.full as the array in a gridded2d.matrix)
            
        .. note::  We still need to do flux weighting
            
            
        .. rubric:: Regrouping Theory
        
        Given a function :math:`f(E)`, we write the grouped data using fudge's ``flat`` interpolation 
        scheme.  We note that we could write this scheme as an expansion over basis functions:
        
        .. math::    
            f(E) = \sum_{i=0}^{N+1} w_i(E) * f_i
        
        where the weight functions :math:`w_i(E)` are
        
        .. math::
            w_i(E) = 1  \;\\text{for}\; E_i <= E <= E_{i+1}; \;\; 0 \;\\textrm{otherwise}
            
        These weights are an orthogonal (bot not orthonormal) basis, with 
        
        .. math::
            (E_{i+1}-E_i) \delta_{ij} = \int dE w_i(E) * w_j(E)
        
        So, to transform from basis :math:`w_i(E)` to :math:`v_i(E)` (which has group boundaries 
        :math:`[ E'_0, ... ]`), do: 
        
        .. math::
            f'_j = \sum_i m_{ji} f_i
            
        where :math:`f'` is the regrouped function coefficients and :math:`m_{ji}` is the matrix
        
        .. math::
            m_{ij} = (E'_{i+1}-E'_i)^{-1} \int dE v_i(E) w_j(E) 

            
        .. rubric:: Applying regrouping theory to covariance matrices   
        
        When we are given a covariance matrix :math:`c_{ij}` in ENDF, it is meant to be interpreted
        as a grouped covariance in both the direction of the matrix rows and the matrix 
        columns.  Therefore, we must regroup in both the row direction and the column 
        direction.  The ENDF format gives both the group boundaries for the rows and columns.
        In other words, ENDF gives us the following rule for evaluating the continuous row-
        column covariance:
        
        .. math::
            c( E1, E2 ) = \sum_{ij} w_i(E1) w_j(E2) c_{ij}
            
        Computing :math:`m_{ij}` as before, 
            
        .. math::
            cc_{ij} = \sum_{i',j'} m_{ii'} c_{i'j'} m_{j'j}
            
        It is straightforward to generalize to the case where the row and column bases are 
        different.
        
        In the routine below, we abuse :py:class:`xData.XYs1d` to specify the functions 
        :math:`w_i(E)` and use the :py:func:`XYs1d.groupOneFunction()` method to perform the integrals to get
        the regrouping matrix.  We do this separately for the rows and the columns.
        The matrix multiplication that converts a covariance from one pair of bases (group 
        structures) to another is accomplished using numpy.

        
        .. rubric:: An explanation of fudge's 'flat' interpolation
        
        Suppose we have a function :math:`f(E)` specified using fudge's `'flat'` interpolation.  
        Then we have :math:`N` entries :math:`[f_0, f_1, ..., f_{N-1}]` and a set of group 
        boundaries :math:`[E_0, E_1, ..., E_N]` and the following rule for interpolation:
        
            * Below :math:`E_0`, :math:`f(E)` evaluates to :math:`0.0`
            * From :math:`E_0 \\rightarrow E_1`, :math:`f(E)` evaluates to :math:`f_0`
            * From :math:`E_1 \\rightarrow E_2`, :math:`f(E)` evaluates to :math:`f_1`
            * ...
            * From :math:`E_{i} \\rightarrow E_{i+1}`, :math:`f(E)` evaluates to :math:`f_i`
            * ...
            * From :math:`E_{N-1} \\rightarrow E_N`, :math:`f(E)` evaluates to :math:`f_{N-1}`
            * Above :math:`E_N`, :math:`f(E)` evaluates to :math:`0.0`
        '''
        # determine where to get the settings for the potentially mirrored second axis
        if self.matrix.axes[1].style == 'link': axis1index = 2
        else:                                   axis1index = 1
        
        # setup the old axes in a form we can (ab)use in the XYs1d class
        axes2_ = axesModule.axes( labelsUnits={1:( self.matrix.axes[2].label, self.matrix.axes[2].unit ),0:( 'dummy', '' )} )
        axes1_ = axesModule.axes( labelsUnits={1:( self.matrix.axes[axis1index].label, self.matrix.axes[axis1index].unit ),0:( 'dummy', '' )} )
        
        # define basis functions for the rows and columns
        basis2 = XYsModule.XYs1d( axes=axes2_, data=[ ( x, 0.0 ) for x in self.matrix.axes[2].values ], interpolation='flat' )
        basis1 = XYsModule.XYs1d( axes=axes1_, data=[ ( x, 0.0 ) for x in self.matrix.axes[axis1index].values ], interpolation='flat' )
        basis2 = basis2.convertAxisToUnit( 1, groupUnit[0] )
        basis1 = basis1.convertAxisToUnit( 1, groupUnit[1] )

        # build the regrouping matrices for the two bases
        w0 = []
        for idx in range( self.matrix.array.shape[0] ):
            basis2[idx] = ( basis2[idx][0], 1.0 )
            w0.append( basis2.groupOneFunction( groupBoundaries[0], norm = 'dx' ) )
            basis2[idx] = ( basis2[idx][0], 0.0 )
        w0 = numpy.mat( w0 )
        w1 = []
        for j in range( self.matrix.array.shape[1] ):
            basis1[j] = ( basis1[j][0], 1.0 )
            w1.append( basis1.groupOneFunction( groupBoundaries[1], norm = 'dx' ) )
            basis1[j] = ( basis1[j][0], 0.0 )
        w1 = numpy.mat( w1 )
                
        # set up the regrouped covariance matrix
        grouped = copy.copy( self )
        grouped.matrix.axes[2].data = groupBoundaries[0]
        grouped.matrix.axes[1].data = groupBoundaries[1]
        grouped.matrix.axes[2].unit = groupUnit[0]
        grouped.matrix.axes[1].unit = groupUnit[1]
        odata = numpy.mat( self.matrix.array.constructArray() )
        gdata = w0.T * odata * w1
        trigdata = gdata[numpy.tri(gdata.shape[0])==1.0].tolist()[0]
        grouped.matrix.array = arrayModule.full(shape=gdata.shape,data=trigdata,symmetry=arrayModule.symmetryLowerToken)
        return grouped