Exemplo n.º 1
0
 def _processIndexChunk(self, what, chunk):
     key = what.lower()
     if key not in self._indxMap:
         raise SerpentToolsException(
             'Could not find proper index map for quantity '
             '{}'.format(what)
         )
     datum = self._indxMap[key]
     indx = 0
     store = False
     for line in chunk:
         if 'SENS' in line:
             store = True
             continue
         if '];' in line:
             return
         if store:
             start = line.index('\'') + 1 if '\'' in line else 0
             stop = -1
             key = line[start:stop].replace('\'', '').strip()
             if '%' in key:
                 key = key.split('% ')[1]
             datum[key] = indx
             indx += 1
     raise SerpentToolsException(
         "Unexpected index chunk {}".format(chunk))
Exemplo n.º 2
0
    def getFY(self, parent, energy, daughter, flagEnergy=True):
        """
        Return a specific fission yield given the parent ID, neutron energy
         and daughter ID

        If the energy does not exist in the results, the fission yield
        corresponding to the closest energy is returned

        Parameters
        ----------
        parent: int or float
            ID of the parent undergoing fission
        energy: float
            neutron energy in MeV
        daughter: int or float
            ID of the fission product
        flagEnergy: boolean
            If set to true, the function will return the fission yield
            that matches to the closest energy given by the user

        Returns
        -------
        indYield: float
                    Independent fission yield
        cumYield: float
                    Cumulative fission yield

        Raises
        ------
        SerpentToolsException:
            If energy is a negative number
            If parent or fission product are not found
        """
        if energy < 0:
            raise SerpentToolsException("Energy entry {0} must be positive"
                                        " in {1}".format(
                                            energy, self.filePath))
        if flagEnergy:
            # obtain the different energies for a specific parent
            eneList = [
                items[1] for items in self.nfy.keys() if parent == items[0]
            ]
            # obtain the closest energy value
            energy = min(eneList,
                         key=lambda x: abs(x - energy)) if eneList else energy
        if (parent, energy) not in self.nfy.keys():
            raise SerpentToolsException("There is no parent {0} with energy "
                                        "{1} in {2}".format(
                                            parent, energy, self.filePath))
        FP = self.nfy[(parent, energy)]['fissProd']
        IndYield = self.nfy[(parent, energy)]['indYield']
        CumYield = self.nfy[(parent, energy)]['cumYield']
        if daughter in FP:
            return (float(IndYield[FP == daughter]),
                    float(CumYield[FP == daughter]))
        raise SerpentToolsException(
            "There is no fission product {0} for parent {1} at energy {2} in "
            "{3}".format(daughter, parent, energy, self.filePath))
Exemplo n.º 3
0
    def addUniverse(self, univID, burnup=0, burnIndex=0, burnDays=0):
        """
        Add a universe to this branch.

        Data for the universes are produced at specific points in time.
        The additional arguments help track of when the data for this
        universe were created.
        A negative value of ``burnup`` indicates the units on burnup are
        really ``days``. Therefore, the value of ``burnDays`` and ``burnup``
        will be swapped.

        .. warning::

            This method will overwrite data for universes that already exist

        Parameters
        ----------
        univID: int or str
            Identifier for this universe
        burnup: float or int
            Value of burnup [MWd/kgU]. A negative value here indicates
            the value is really in units of days.
        burnIndex: int
            Point in the depletion schedule
        burnDays: int or float
            Point in time

        Returns
        -------
        serpentTools.objects.containers.HomogUniv
            Empty new universe

        """
        if self.__hasDays is None and burnup:
            self.__hasDays = burnup < 0
        if burnup < 0:
            if not self.__hasDays:
                raise SerpentToolsException(
                    self.__mismatchedBurnup.format('negative', 'MWd/kgU'))
            burnup, burnDays = None if burnup else 0, -burnup
        else:
            if self.__hasDays and not burnDays:
                raise SerpentToolsException(
                    self.__mismatchedBurnup.format('positive', 'days'))
            burnDays = None if burnup else 0
        newUniv = HomogUniv(univID, burnup, burnIndex, burnDays)
        key = (univID, burnup or burnDays, burnIndex)
        if key in self.__keys:
            warning('Overwriting existing universe {} in {}'.format(
                key, str(self)))
        else:
            self.__keys.add(key)
        self.universes[key] = newUniv
        return newUniv
Exemplo n.º 4
0
def inferReader(filePath):
    """
    Attempt to infer the correct reader type.

    Parameters
    ----------
    filePath: str or path-like
        File to be read.

    Raises
    ------
    SerpentToolsException
        If a reader cannot be inferred
    """
    filePath = str(filePath)
    for reg, reader in REGEXES.items():
        match = re.match(reg, filePath)
        if match and match.group() == filePath:
            debug('Inferred reader for {}: {}'
                  .format(filePath, reader.__name__))
            return reader
    raise SerpentToolsException(
        'Failed to infer filetype and thus accurate reader from'
        'file path {}. Pass one of the below options to ensure '
        'a specific reader:\n{}'.format(filePath, SUPPORTED_READER_MSG)
    )
Exemplo n.º 5
0
 def __init__(self, name, bu, step, day):
     if not all(xx is None or xx >= 0 for xx in (bu, step, day)):
         tail = [
             '{}: {}'.format(valName, val)
             for valName, val in zip(('burnup', 'index', 'days'), (bu, step,
                                                                   day))
         ]
         raise SerpentToolsException(
             "Will not create universe with negative burnup\n{}".format(
                 ', '.join(tail)))
     NamedObject.__init__(self, name)
     if step == 0:
         bu = bu if bu is not None else 0.0
         day = day if day is not None else 0.0
     self.bu = bu
     self.step = step
     self.day = day
     # Dictionaries:
     self.b1Exp = {}
     self.infExp = {}
     self.b1Unc = {}
     self.infUnc = {}
     self.gc = {}
     self.gcUnc = {}
     self.__reshaped = rc['xs.reshapeScatter']
     self._numGroups = None
     self.groups = None
     self.microGroups = None
     self._numMicroGroups = None
Exemplo n.º 6
0
    def _gather_univdata(self, func):
        numAppearances = {}

        for key in self.universes:
            if key.universe not in numAppearances:
                numAppearances[key.universe] = 1
                continue
            numAppearances[key.universe] += 1
        # check to make sure all universes appear an identical
        # number of times
        burnupVals = set(numAppearances.values())
        if len(burnupVals) != 1:
            raise SerpentToolsException(
                "Universes appear a different number of times:\n{}".format(
                    numAppearances))

        shapeStart = burnupVals.pop(), len(numAppearances)
        univOrder = tuple(sorted(numAppearances))

        univData = {func('universes'): univOrder}

        for univKey, univ in self.universes.items():

            # position in matrix
            uIndex = univOrder.index(univKey.universe)
            bIndex = univKey.step

            for expName, uncName in zip(('infExp', 'b1Exp', 'gc'),
                                        ('infUnc', 'b1Unc', 'gcUnc')):
                expD = getattr(univ, expName)
                uncD = getattr(univ, uncName)
                gatherPairedUnivData(univ, uIndex, bIndex, shapeStart, func,
                                     expD, uncD, univData)

        return univData
Exemplo n.º 7
0
 def _getMatch(self, line, regex, desc):
     match = regex.search(line)
     if match is not None:
         return match
     raise SerpentToolsException(
         "Depmtx reader failed to match {} from {}:\n{}".format(
             desc, self.filePath, line))
Exemplo n.º 8
0
    def spreadPlot(self, xdim=None, fixed=None, sampleKwargs=None,
                   meanKwargs=None, ax=None, xlabel=None,
                   ylabel=None, logx=False, logy=False, loglog=False,
                   legend=True):
        """
        Plot the mean tally value against all sampled detector data.

        Parameters
        ----------
        xdim: str
            Bin index to place on the x-axis
        fixed: None or dict
            Dictionary controlling the reduction in data down to one dimension
        sampleKwargs : dict, optional
            Additional matplotlib-acceptable arguments to be passed into the
            plot when plotting data from unique runs, e.g.
            ``{"c": k, "alpha": 0.5}``.
        meanKwargs : dict, optional
            Additional matplotlib-acceptable argumentst to be used when
            plotting the mean value, e.g. ``{"c": "b", "marker": "o"}``
        {ax}
        {xlabel}
        {ylabel}
        {logx}
        {logy}
        {loglog}
        {legend}

        Returns
        -------
        {rax}

        """
        if self.allTallies is None:
            raise AttributeError(
                "allTallies is None, cannot plot all tally data")

        samplerData = self.slice(fixed, 'tallies')
        slices = self._getSlices(fixed)
        if len(samplerData.shape) != 1:
            raise SerpentToolsException(
                'Data must be constrained to 1D, not {}'.format(
                    samplerData.shape))
        xdata, autoX = self._getPlotXData(xdim, samplerData)
        xlabel = xlabel or autoX

        if sampleKwargs is None:
            sampleKwargs = {"c": "k", "alpha": 0.5, "marker": ""}
        if meanKwargs is None:
            meanKwargs = {"c": "#0173b2", "marker": "o"}

        ax = ax or pyplot.gca()
        for data in self.allTallies:
            ax.plot(xdata, data[slices], **sampleKwargs)

        ax.plot(xdata, samplerData, label='Mean value', **meanKwargs)
        formatPlot(ax, logx=logx, logy=logy, loglog=loglog, xlabel=xlabel,
                   ylabel=ylabel, legend=legend)
        return ax
Exemplo n.º 9
0
    def getXS(self, universe, isotope, reaction, isomeric=0):
        """
        Return the group-wise micro cross-sections for a
        specific isotope, and reaction

        Parameters
        ----------
        universe: string
            universe ID, e.g., `0`
        isotope: int or float
            ID of the isotope (ZZAAA0/1)
        reaction: int
            MT reaction, e.g., 102 --> (n,gamma)
        Special flag: int or float
            Isomeric state or fission yield distribution number
            Default is zero

        Returns
        -------
        xsVal: numpy.ndarray
                    Group-wise cross-section values
        xsUnc: numpy.ndarray
                    Group-wise uncertainty values

        Raises
        ------
        SerpentToolsException:
            If the universe does not exist
            If the isotope's format is incorrect (not ZZAAA0/1)
        """
        if universe not in self.xsVal.keys():
            raise SerpentToolsException(
                "Universe {0} does not exist in {1}".format(
                    universe, self.filePath))
        if isotope < 10010 or isotope > 1000000:
            raise SerpentToolsException("Isotope {0} is not properly formatted"
                                        " ZZAAA0/1 in {1}".format(
                                            isotope, self.filePath))
        key = (isotope, reaction, isomeric)
        if key in self.xsVal[universe]:
            return (self.xsVal[universe][key], self.xsUnc[universe][key])
        raise SerpentToolsException("There is no isotope {0} with reaction {1}"
                                    " and isomeric flag {2} in {3}".format(
                                        isotope, reaction, isomeric,
                                        self.filePath))
Exemplo n.º 10
0
 def orderedUniv(self):
     """Universe keys sorted by ID and by burnup"""
     if not any(self):
         raise SerpentToolsException(
             'No universes stored on branch {}'.format(str(self)))
     if self._orderedUniverses is None:
         self._orderedUniverses = tuple(
             sorted(self, key=lambda tpl: (tpl.universe, tpl.step)))
     return self._orderedUniverses
Exemplo n.º 11
0
 def _inspectData(self):
     """ensure the parser grabbed expected materials."""
     obtainedRes = (self._counter['meta'] // self._numUniv
                    if self._numUniv else self._counter['meta'])
     if obtainedRes != self._counter['rslt']:
         raise SerpentToolsException(
             "The file {} is not complete. The reader found {} universes, "
             "{} time-points, and {} overall result points ".format(
                 self.filePath, self._numUniv, self._counter['rslt'],
                 self._counter['meta']))
     if not self.resdata and not self.metadata:
         for keys, dictUniv in self.universes.items():
             if dictUniv.hasData():
                 return
         raise SerpentToolsException(
             "metadata, resdata and universes are all empty "
             "from {} and <results.expectGcu> is True".format(
                 self.filePath))
Exemplo n.º 12
0
    def slice(self, fixed, data='tallies'):
        """
        Return a view of the reshaped array where certain axes are fixed

        Parameters
        ----------
        fixed: dict
            dictionary to aid in the restriction on the multidimensional
            array. Keys correspond to the various grids present in
            ``indexes`` while the values are used to
        data: {'tallies', 'errors', 'scores'}
            Which data set to slice

        Returns
        -------
        :class:`numpy.ndarray`
            View into the respective data where certain dimensions
            have been removed

        Raises
        ------
        SerpentToolsException
            If the data has not been reshaped or is None [e.g. scores]
        KeyError
            If the data set to slice not in the allowed selection

        """
        if not self._isReshaped():
            raise SerpentToolsException(
                'Slicing requires detector to be reshaped')
        if data not in self._map:
            raise KeyError(
                'Data argument {} not in allowed options'
                '\n{}'.format(data, ', '.join(self._map.keys())))
        work = self._map[data]
        if work is None:
            raise SerpentToolsException(
                '{} data for detector {} is None. '
                'Cannot perform slicing'.format(data, self.name))
        if not fixed:
            return work
        return work[self._getSlices(fixed)]
Exemplo n.º 13
0
 def _processNumChunk(self, chunk):
     chunk = [line for line in chunk if 'SENS' in line]
     for line in chunk:
         split = line.split()
         attrN = 'n' + split[0].split('_')[-1].capitalize()
         if hasattr(self, attrN):
             setattr(self, attrN, int(split[-1][:-1]))
         else:
             raise SerpentToolsException(
                 'Attempted to set attribute {} from number block'.format(
                     attrN))
Exemplo n.º 14
0
 def _precheck(self):
     """do a quick scan to ensure this looks like mdx file."""
     with open(self.filePath) as fid:
         if fid is None:
             raise IOError("Attempting to read on a closed file.\n"
                           "Parser: {}\nFile: {}".format(
                               self, self.filePath))
         for tline in fid:
             if 'NFY' in tline:
                 return
         raise SerpentToolsException("Fission yields values were not "
                                     "found in {}".format(self.filePath))
Exemplo n.º 15
0
    def reshape(self):
        """
        Reshape the tally data into a multidimensional array

        This method reshapes the tally and uncertainty data into arrays
        where the array axes correspond to specific bin types.
        If a detector was set up to tally two group flux in a 5 x 5
        xy mesh, then the resulting tally data would be in a 50 x 12/13
        matrix in the original ``detN.m`` file.
        The tally data and relative error would be rebroadcasted into
        2 x 5 x 5 arrays, and the indexing information is stored in
        ``self.indexes``

        Returns
        -------
        shape: list
            Dimensionality of the resulting array

        Raises
        ------
        SerpentToolsException:
            If the bin data has not been loaded
        """
        if self.bins is None:
            raise SerpentToolsException('Tally data for detector {} has not '
                                        'been loaded'.format(self.name))
        if self.__reshaped:
            warning('Data has already been reshaped')
            return
        shape = []
        self.indexes = OrderedDict()
        hasScores = self.bins.shape[1] == 13
        if self.bins.shape[0] == 1:
            self.tallies = self.bins[0, 10]
            self.errors = self.bins[0, 11]
            if hasScores:
                self.scores = self.bins[0, 12]
        else:
            for index in range(1, 10):
                uniqueVals = unique(self.bins[:, index])
                if len(uniqueVals) > 1:
                    indexName = self._indexName(index)
                    self.indexes[indexName] = array(uniqueVals, dtype=int) - 1
                    shape.append(len(uniqueVals))
            self.tallies = self.bins[:, 10].reshape(shape)
            self.errors = self.bins[:, 11].reshape(shape)
            if hasScores:
                self.scores = self.bins[:, 12].reshape(shape)
        self._map = {'tallies': self.tallies, 'errors': self.errors,
                     'scores': self.scores}
        self.__reshaped = True
        return shape
Exemplo n.º 16
0
    def getUniv(self, univ, burnup=None, index=None, timeDays=None):
        """
        Return a specific universe given the ID and time of interest

        If more than one time parameter is given, the hierarchy of search is:
        index (highest priority), burnup, timeDays (lowest priority)

        Parameters
        ----------
        univ: str
            Unique str for the desired universe
        burnup: float or int
            Burnup [MWd/kgU] of the desired universe
        timeDays: float or int
            Time [days] of the desired universe
        index: int
            Point of interest in the burnup/days index

        Returns
        -------
        :py:class:`~serpentTools.objects.containers.HomogUniv`
            Requested universe

        Raises
        ------
        KeyError:
            If the requested universe could not be found
        SerpentToolsException:
            If burnup, days and index are not given
        """
        if index is None and burnup is None and timeDays is None:
            raise SerpentToolsException(
                'Burnup, time or index are required inputs')
        searchIndex = (2 if index is not None else
                       1 if burnup is not None else 3)
        searchValue = (index if index is not None else
                       burnup if burnup is not None else timeDays)
        if searchIndex == 2 and searchValue < 1:  # index must be non-zero
            raise KeyError(
                'Index read is {}, however only integers above zero are '
                'allowed'.format(searchValue))
        for key, dictUniv in iteritems(self.universes):
            if key[0] == univ and key[searchIndex] == searchValue:
                debug('Found universe that matches with keys {}'.format(key))
                return self.universes[key]
        searchName = ('index '
                      if index else 'burnup ' if burnup else 'timeDays ')
        raise KeyError(
            'Could not find a universe that matched requested universe {} and '
            '{} {}'.format(univ, searchName, searchValue))
Exemplo n.º 17
0
    def getUniv(self, univ, burnup=None, index=None, timeDays=None):
        """
        Return a specific universe given the ID and time of interest

        Parameters
        ----------
        univ: str
            Unique str for the desired universe
        burnup: float or int, optional
            Burnup [MWd/kgU] of the desired universe
        timeDays: float or int, optional
            Time [days] of the desired universe
        index: int, optinal
            Point of interest in the burnup/days index

        Returns
        -------
        :class:`~serpentTools.objects.HomogUniv`
            Requested universe

        Raises
        ------
        KeyError:
            If the requested universe could not be found
        :class:`~serpentTools.SerpentToolsException`
            If burnup, days and index are not given
        """
        if index is None and burnup is None and timeDays is None:
            raise SerpentToolsException(
                'Burnup, time or index are required inputs')

        searchKey = UnivTuple(univ, burnup, index, timeDays)

        # check if key is exactly present

        universe = self.universes.get(searchKey)
        if universe is not None:
            return universe

        for key, universe in iteritems(self.universes):
            for uItem, sItem in zip(key, searchKey):
                if sItem is None:
                    continue
                elif uItem != sItem:
                    break
            else:
                return universe
        raise KeyError(
            "Could not find a universe that matches {}".format(searchKey))
Exemplo n.º 18
0
    def _storeResData(self, varNamePy, varVals):
        """Process time-dependent results data"""
        vals = str2vec(varVals)  # convert the string to float numbers

        stored = self._tempArrays.get(varNamePy)
        if stored is None:
            self._tempArrays[varNamePy] = ListOfArrays(vals)
        elif len(stored) < self._counter['rslt']:
            # append this data only once!
            try:
                stored.append(vals)
            except Exception as ee:
                raise SerpentToolsException(
                    "Error in appending {}  into {} of resdata:\n{}".format(
                        varNamePy, vals, str(ee)))
Exemplo n.º 19
0
 def __processEnergyChunk(self, chunk):
     for line in chunk:
         if 'SENS' == line[:4]:
             break
     else:
         raise SerpentToolsException("Could not find SENS parameter "
                                     "in energy chunk {}".format(chunk[:3]))
     splitLine = line.split()
     varName = splitLine[0].split('_')[1:]
     varValues = str2vec(splitLine[3:-1])
     if varName[0] == 'E':
         self.energies = varValues
     elif varName == ['LETHARGY', 'WIDTHS']:
         self.lethargyWidths = varValues
     else:
         warning("Unanticipated energy setting {}".format(splitLine[0]))
Exemplo n.º 20
0
 def _storeResData(self, varNamePy, varVals):
     """Process time-dependent results data"""
     vals = str2vec(varVals)  # convert the string to float numbers
     if varNamePy in self.resdata.keys():  # extend existing matrix
         currVar = self.resdata[varNamePy]
         ndim = 1
         if len(currVar.shape) == 2:
             ndim = currVar.shape[0]
         if ndim < self._counter['rslt']:
             # append this data only once!
             try:
                 stacked = vstack([self.resdata[varNamePy], vals])
                 self.resdata[varNamePy] = stacked
             except Exception as ee:
                 raise SerpentToolsException(
                     "Error in appending {}  into {} of resdata:\n{}".
                     format(varNamePy, vals, str(ee)))
     else:
         self.resdata[varNamePy] = array(vals)  # define a new matrix
Exemplo n.º 21
0
    def getUniv(self, univID, burnup=None, index=None, days=None):
        """
        Return a specific universe given the ID and time of interest

        Parameters
        ----------
        univID: str
            Unique ID for the desired universe
        burnup: float, optional
            Burnup [MWd/kgU] of the desired universe
        index: int, optional
            Point of interest in the burnup index
        days : float, optional
            Point in time [d] for the desired universe

        Returns
        -------
        :class:`~serpentTools.objects.HomogUniv`
            Requested universe

        Raises
        ------
        KeyError
            If the requested universe could not be found
        :class:`serpentTools.SerpentToolsException`
            If neither burnup nor index are given
        """
        if burnup is None and index is None:
            raise SerpentToolsException('Burnup or index are required inputs')

        searchKey = UnivTuple(univID, burnup, index, days)

        for key, universe in self.items():
            for uItem, sItem in zip(key, searchKey):
                if sItem is None:
                    continue
                if uItem != sItem:
                    break
            else:
                return universe
        raise KeyError(
            "Could not find a universe matching {}".format(searchKey))
Exemplo n.º 22
0
    def getUniv(self, univID, burnup=None, index=None):
        """
        Return a specific universe given the ID and time of interest

        If burnup and index are given, burnup is used to search

        Parameters
        ----------
        univID: int
            Unique ID for the desired universe
        burnup: float or int
            Burnup [MWd/kgU] of the desired universe
        index: int
            Point of interest in the burnup index

        Returns
        -------
        :py:class:`~serpentTools.objects.containers.HomogUniv`
            Requested universe

        Raises
        ------
        KeyError:
            If the requested universe could not be found
        SerpentToolsException:
            If neither burnup nor index are given
        """
        if burnup is None and index is None:
            raise SerpentToolsException('Burnup or index are required inputs')
        searchIndex = 2 if index is not None else 1
        searchValue = index if index is not None else burnup
        for key in self.__keys:
            if key[0] == univID and key[searchIndex] == searchValue:
                debug('Found universe that matches with keys {}'.format(key))
                return self.universes[key]
        searchName = 'burnup' + ('' if index is None else ' index')
        raise KeyError(
            'Could not find a universe that matched requested universe {} and '
            '{} {}'.format(univID, searchName, searchValue))
Exemplo n.º 23
0
def inferReader(filePath):
    """
    Attempt to infer the correct reader type.

    Parameters
    ----------
    filePath: str
        File to be read.

    Raises
    ------
    SerpentToolsException
        If a reader cannot be inferred
    """
    for reg, reader in six.iteritems(REGEXES):
        match = re.match(reg, filePath)
        if match and match.group() == filePath:
            debug('Inferred reader for {}: {}'.format(filePath,
                                                      reader.__name__))
            return reader
    raise SerpentToolsException(
        'Failed to infer filetype and thus accurate reader from'
        'file path {}'.format(filePath))
Exemplo n.º 24
0
 def __init__(self, name, bu, step, day):
     if not all(isNonNeg(xx) for xx in (bu, step, day)):
         tail = [
             '{}: {}'.format(name, val)
             for name, val in zip(('burnup', 'index', 'days'), (bu, step,
                                                                day))
         ]
         raise SerpentToolsException(
             "Will not create universe with negative burnup\n{}".format(
                 ', '.join(tail)))
     NamedObject.__init__(self, name)
     if step is not None and step == 0:
         bu = bu if bu is not None else 0.0
         day = day if day is not None else 0.0
     self.bu = bu
     self.step = step
     self.day = day
     # Dictionaries:
     self.b1Exp = {}
     self.infExp = {}
     self.b1Unc = {}
     self.infUnc = {}
     self.metadata = {}
Exemplo n.º 25
0
def cleanDetChunk(chunk):
    """
    Return the name of the detector [grid] and the array of data.

    Parameters
    ----------
    chunk: list
        Chunk of text from the output file pertaining to this section.
        Should begin with ``DET<name>[<grid>] = [`` with
        array data on the subsequent lines

    Returns
    -------
    str:
        Name of the detector including grid characters
    numpy.ndarray:
        Array containing numeric data from the chunk

    Raises
    ------
    SerpentToolsException:
        If the name of the detector could not be determined
    """
    if chunk[0][:3] != 'DET':
        raise SerpentToolsException(
            "Could not determine name of detector from chunk: {}".format(
                chunk[0]))
    leader = chunk.pop(0)
    name = leader.split()[0][3:]
    if chunk[-1][:2] == '];':
        chunk.pop(-1)
    nCols = len(chunk[0].split())
    data = empty((len(chunk), nCols), order='F')
    for indx, row in enumerate(chunk):
        data[indx] = str2vec(row)
    return name, data
Exemplo n.º 26
0
    def meshPlot(self,
                 xdim,
                 ydim,
                 what='tallies',
                 fixed=None,
                 ax=None,
                 cmap=None,
                 logColor=False,
                 xlabel=None,
                 ylabel=None,
                 logx=False,
                 logy=False,
                 loglog=False,
                 **kwargs):
        """
        Plot tally data as a function of two mesh dimensions

        Parameters
        ----------
        xdim: str
            Primary dimension - will correspond to x-axis on plot
        ydim: str
            Secondary dimension - will correspond to y-axis on plot
        what: {'tallies', 'errors', 'scores'}
            Color meshes from tally data, uncertainties, or scores
        fixed: None or dict
            Dictionary controlling the reduction in data down to one dimension
        {ax}
        {cmap}
        logColor: bool
            If true, apply a logarithmic coloring to the data positive 
            data
        {xlabel}
        {ylabel}
        {logx}
        {logy}
        {loglog}
        {kwargs} :py:func:`~matplotlib.pyplot.pcolormesh`

        Returns
        -------
        {rax}

        Raises
        ------
        SerpentToolsException
            If data to be plotted, with or without constraints, is not 1D
        KeyError
            If the data set by ``what`` not in the allowed selection
        ValueError
            If the data contains negative quantities and ``logColor`` is
            ``True``

        See Also
        --------
        * :py:meth:`~serpentTools.objects.containers.DetectorBase.slice`
        * :py:func:`matplotlib.pyplot.pcolormesh`
        * :py:func:`~serpentTools.plot.cartMeshPlot`
        """
        if fixed:
            for qty, name in zip((xdim, ydim), ('x', 'y')):
                if qty in fixed:
                    raise SerpentToolsException(
                        'Requested {} dimension {} is one of the axis to be constrained. '
                        .format(name, qty))

        data = self.slice(fixed, what)
        dShape = data.shape
        if len(dShape) != 2:
            raise SerpentToolsException(
                'Data must be 2D for mesh plot, currently is {}.\nConstraints:'
                '{}'.format(dShape, fixed))
        xgrid = self._getGrid(xdim)
        ygrid = self._getGrid(ydim)
        if data.shape != (ygrid.size - 1, xgrid.size - 1):
            data = data.T

        ax = cartMeshPlot(data, xgrid, ygrid, ax, cmap, logColor, **kwargs)
        ax.set_xlabel(xlabel or xdim)
        ax.set_ylabel(ylabel or ydim)
        if loglog or logx:
            ax.set_xscale('log')
        if loglog or logy:
            ax.set_yscale('log')
        return ax
Exemplo n.º 27
0
    def plot(self, xUnits, yUnits=None, timePoints=None, names=None, zai=None,
             materials=None, ax=None, legend=None, logx=False, logy=False,
             loglog=False, labelFmt=None, xlabel=None, ylabel=None, ncol=1,
             **kwargs):
        """
        Plot properties for all materials in this file together.

        Parameters
        ----------
        xUnits: str
            If ``xUnits`` is given and ``yUnits`` is ``None``, then
            the plotted data will be ``xUnits`` against ``'days'``
            name of x value to obtain, e.g. ``'days'``, ``'burnup'``
        yUnits: str
            name of y value to return, e.g. ``'adens'``, ``'ingTox'``
        timePoints: list or None
            If given, select the time points according to those
            specified here. Otherwise, select all points

            .. deprecated:: 0.7.0
               Will plot against all time points

        names: str or list or None
            If given, plot  values corresponding to these isotope
            names. Otherwise, plot values for all isotopes.
        zai: int or list or None
            If given, plot values corresponding to these
            isotope ``ZZAAAI`` values. Otherwise, plot for all isotopes

            .. versionadded:: 0.5.1

        materials: None or list
            Selection of materials from ``self.materials`` to plot.
            If None, plot all materials, potentially including ``tot``
        {ax}
        {legend}
        {xlabel} Otherwise, use ``xUnits``
        {ylabel} Otherwise, use ``yUnits``
        {logx}
        {logy}
        {loglog}
        {matLabelFmt}
        {ncol}
        {kwargs} :py:func:`matplotlib.pyplot.plot`

        Returns
        -------
        {rax}

        See Also
        --------
        * :py:func:`~serpentTools.objects.materials.DepletedMaterial.getValues`
        * :py:func:`matplotlib.pyplot.plot`
        * :py:meth:`str.format` - used for formatting labels
        * :py:func:`~serpentTools.objects.materials.DepletedMaterial.plot`

        Raises
        ------
        KeyError
            If x axis units are not ``'days'`` nor ``'burnup'``
        SerpentToolsException
            If the materials dictionary does not contain any items
        """
        if yUnits is None:
            yUnits = xUnits
            xUnits = 'days'

        if not self.materials:
            raise SerpentToolsException("Material dictionary is empty")

        if xUnits not in ('days', 'burnup'):
            raise KeyError("Plot method only uses x-axis data from <days> and "
                           "<burnup>, not {}".format(xUnits))
        missing = set()
        ax = ax or pyplot.gca()
        materials = materials or self.materials.keys()
        labelFmt = labelFmt or '{mat} {iso}'
        for mat in materials:
            if mat not in self.materials:
                missing.add(mat)
                continue

            ax = self.materials[mat].plot(
                xUnits, yUnits, timePoints, names,
                zai, ax, legend=False, xlabel=xlabel, ylabel=ylabel,
                logx=False, logy=False, loglog=False, labelFmt=labelFmt,
                **kwargs)
        if missing:
            warning("The following materials were not found in materials "
                    "dictionary: {}".format(', '.join(missing)))
        formatPlot(ax, legend=legend, legendcols=ncol, logx=logx, logy=logy,
                   loglog=loglog,
                   xlabel=xlabel or DEPLETION_PLOT_LABELS[xUnits],
                   ylabel=ylabel or DEPLETION_PLOT_LABELS[yUnits],
                   )

        return ax
Exemplo n.º 28
0
def read(filePath, reader='infer'):
    """
    Simple entry point to read a file and obtain the processed reader.

    Parameters
    ----------
    filePath: str
        Path to the file to be reader
    reader: str or callable
        Type of reader to use. If a string is given, then
        the actions described below will happen. If callable,
        then that function will be used with the file
        path as the first argument.

        =============== ==========================================
        String argument Action
        =============== ==========================================
        infer           Infer the correct reader based on the file
        branch          ``BranchingReader``
        bumat           ``BumatReader``
        dep             ``DepletionReader``
        det             ``DetectorReader``
        fission         ``FissionMatrixReader``
        history         ``HistoryReader``
        microxs         ``MdxReader``
        results         ``ResultsReader``
        sensitivity     ``SensitivityReader``
        xsplot          ``XSPlotReader``
        =============== ==========================================

    Returns
    -------
    serpentTools.objects.base.BaseReader
        Correct subclass corresponding to the file type

    Raises
    ------
    AttributeError
        If the object created by the reader through
        ``reader(filePath)`` does not have a ``read`` method.
    SerpentToolsException
        If the reader could not be inferred or if the requested
        reader string is not supported
    NotImplementedError
        This has the ability to load in readers that may not be
        complete, and thus the ``read`` method may raise
        this error.
    """
    if isinstance(reader, str):
        if reader == 'infer':
            loader = inferReader(filePath)
        else:
            if reader in READERS:
                loader = READERS[reader]
            else:
                raise SerpentToolsException(
                    'Reader type {} not supported. Try one of the below:\n{}'.
                    format(reader, SUPPORTED_READER_MSG))
    else:
        assert callable(reader), ('Reader {} is not callable'.format(
            str(reader)))
        loader = reader
    returnedFromLoader = loader(filePath)
    returnedFromLoader.read()
    return returnedFromLoader
Exemplo n.º 29
0
 def _precheck(self):
     with open(self.filePath) as stream:
         line = stream.readline().strip()
     if line[:4] != 't = ':
         raise SerpentToolsException(
             "File does not appear to be a depmtx file")
Exemplo n.º 30
0
 def _postcheck(self):
     if not self.sensitivities:
         raise SerpentToolsException("No sensitivity data stored on reader")
     if not self.energyIntegratedSens:
         raise SerpentToolsException("No energy integrated sensitivities "
                                     "stored on reader")