# <<BEGIN-copyright>>
# <<END-copyright>>
"""A covarianceSuite is organized into sections, where each section contains either
- a covariance matrix for a single reaction quantity (cross section, multiplicity, etc), or
- a covariance matrix between two different quantities (off-diagonal block)
"""
from xData.ancestry import ancestry
from xData import link as linkModule
from fudge.gnds import suites as suitesModule
from . import covarianceMatrix
from .mixed import mixedForm
from .summed import summedCovariance
from pqu import PQU as PQUModule
__metaclass__ = type
[docs]class section( suitesModule.suite ):
"""
A covarianceSuite contains sections, where each section represents either a self-covariance for one quantity,
or a cross-covariance between two quantities
More generally, the covarianceSuite can be thought of as a single covariance matrix with all covariance data
for a target/projectile. It is broken into sections, where each section holds a chunk of the full matrix.
Within each section, covariance data can take multiple forms: :py:class:`covarianceMatrix` is the most common,
but 'summed', 'mixed' are also possible.
Valid values in the :py:attr:`forms` dictionary are:
* mixedForm
* summedCovariance
* covarianceMatrix
"""
moniker = 'section'
def __init__(self, label, rowData=None, columnData=None):
""" each section needs a unique id, pointers to the central values (row and column),
and one or more forms """
suitesModule.suite.__init__( self, [covarianceMatrix, mixedForm, summedCovariance] )
self.label = label #: a str label that gets used on plots, etc.
self.rowData = rowData #: xData.link.link pointing to the corresponding data for the covariance row
self.columnData = columnData #: xData.link.link pointing to the corresponding data for the covariance column
@property
def crossTerm(self):
return self.columnData is not None and self.columnData.link != self.rowData.link
[docs] def check( self, info ):
""" check each section """
from fudge.gnds import warning
warnings = []
for form in self:
formWarnings = form.check( info )
if formWarnings:
warnings.append( warning.context( "Form '%s':" % form.label, formWarnings ) )
return warnings
[docs] def fix( self, **kw ):
"""assemble some useful info, to be handed down to children's check() functions"""
info = {}
warnings = []
if self.rowData is None: info['rowENDF_MFMT'] = None
else: info['rowENDF_MFMT'] = self.rowData['ENDF_MFMT']
if self.columnData is None: info['columnENDF_MFMT'] = None
else: info['columnENDF_MFMT'] = self.columnData['ENDF_MFMT']
info.update( kw )
for form in self: warnings += form.fix( **info )
return warnings
[docs] def toXMLList( self, indent = '', **kwargs ) :
indent2 = indent + kwargs.get( 'incrementalIndent', ' ' )
xmlString = [indent+'<%s label="%s"' % (self.moniker, self.label)]
if self.crossTerm: xmlString[0] += ' crossTerm="true"'
xmlString[0] += '>'
for dataPointer in ('rowData','columnData'):
if getattr(self, dataPointer) is not None:
xmlString.append( getattr(self, dataPointer).toXML( indent2, **kwargs ) )
for form in self:
xmlString += form.toXMLList( indent2, **kwargs )
xmlString[-1] += '</%s>' % self.moniker
return xmlString
[docs] @classmethod
def parseXMLNode( cls, element, xPath, linkData ):
"""Translate <section> element from xml."""
xPath.append( '%s[@label="%s"]' % (element.tag, element.get('label') ) )
linkData['typeConversion'] = {'domainMin':float, 'domainMax':float}
rowData_ = rowData.parseXMLNode( element[0], xPath, linkData )
columnData_ = None
if element[1].tag=="columnData":
columnData_ = columnData.parseXMLNode( element[1], xPath, linkData )
del linkData['typeConversion']
section_ = cls( element.get('label'), rowData_, columnData_ )
start = 2 if (columnData_ is not None) else 1
for form in element[start:]:
formClass = {
covarianceMatrix.moniker: covarianceMatrix,
mixedForm.moniker: mixedForm,
summedCovariance.moniker: summedCovariance,
}.get( form.tag )
if formClass is None:
raise Exception("encountered unknown covariance matrix form '%s'" % form.tag)
section_.add( formClass.parseXMLNode( form, xPath, linkData ) )
xPath.pop()
return section_
[docs]class rowData( linkModule.link ):
moniker = 'rowData'
[docs]class columnData( linkModule.link ):
moniker = 'columnData'