Example #1
0
 def get_element(self, basename, file_handle):
     with uff.FortranFile(file_handle.name, endian=self._endian) as uffile:
         try:
             leading_line = uffile.readline()
         except IOError:
             leading_line = ''
     return leading_line
Example #2
0
def create_bpch(filename, title=DEFAULT_TITLE, filetype=FILETYPE02, **kwargs):
    """
    Create a new empty bpch file.

    Parameters
    ----------
    filename : string
        name or path to the bpch file.
    title : string
        a title line to write in the file's header.
    filetype : string
        bpch file type identifier (either :attr:`bpch.FILETYPE02` or
        :attr:`bpch.FILETYPE4D`).
    **kwargs
        extra parameters passed to :class:`pygchem.utils.uff.FortranFile`
        (e.g., `endian`).

    Returns
    -------
    bpch_file
        the open file instance (:class:`pygchem.utils.uff.FortranFile` object).

    """
    bpch_file = uff.FortranFile(filename, 'wb', **kwargs)
    bpch_file.writeline('40s', filetype.ljust(40))
    bpch_file.writeline('80s', title.ljust(80))
    return bpch_file
Example #3
0
def read_bpch(filename,
              mode='rb',
              skip_data=True,
              diaginfo_file='',
              tracerinfo_file='',
              **kwargs):
    """
    Read the binary punch file v2 format.

    Parameters
    ----------
    filename : string
        name or path to the bpch file.
    mode : {'r', 'r+', rb', 'r+b', 'a'}
        file open mode (see :func:`open`). Writing only ('w' or 'wb') is not
        allowed.
    skip_data : bool
        if True, only data block metadata will be read (it will not load data
        into memory but data position and size information will be provided
        in addition to metadata, so that data can further be easily loaded).
    diaginfo_file : string
        path to the 'diaginfo.dat' file (optional). If empty, it will look
        for 'diaginfo.dat' in the same directory than `filename` or it will
        take a default one.
    tracerinfo_file : string
        path to the 'tracerinfo.dat' file (or empty string).
    **kwargs
        extra parameters passed to :class:`pygchem.utils.uff.FortranFile`
        (e.g., `endian`).
    
    Returns
    -------
    filetype
        bpch file type identifier (given in the file's header)
    filetitle
        title (given in the file's header)
    datablocks
        the list of data blocks, i.e., dictionaries with data block metadata
        and data as a :class:`numpy.ndarray` object or a :class:`BPCHDataProxy`
        instance if `skip_data` is True.

    """
    if mode != 'a' and not mode.endswith('b'):
        mode += 'b'  # platform independent
    if 'w' in mode:
        raise ValueError("write-only mode is not allowed for reading the "
                         "bpch file")

    dir_path = os.path.abspath(os.path.dirname(filename))
    if not dir_path:
        dir_path = os.getcwd()
    if not tracerinfo_file:
        tracerinfo_file = os.path.join(dir_path, "tracerinfo.dat")
        if not os.path.exists(tracerinfo_file):
            tracerinfo_file = ''
    if not diaginfo_file:
        diaginfo_file = os.path.join(dir_path, "diaginfo.dat")
        if not os.path.exists(diaginfo_file):
            diaginfo_file = ''
    ctm_info = CTMDiagnosticInfo(diaginfo_file=diaginfo_file,
                                 tracerinfo_file=tracerinfo_file)

    with uff.FortranFile(filename, mode, **kwargs) as bpch_file:
        datablocks = []
        filetype = bpch_file.readline().strip()
        fsize = os.path.getsize(filename)
        filetitle = bpch_file.readline().strip()

        while bpch_file.tell() < fsize:
            # read first and second header line
            line = bpch_file.readline('20sffii')
            modelname, res0, res1, halfpolar, center180 = line
            line = bpch_file.readline('40si40sdd40s7i')
            category_name, number, unit, tau0, tau1, reserved = line[:6]
            dim0, dim1, dim2, dim3, dim4, dim5, skip = line[6:]

            # get additional metadata from tracerinfo / diaginfo
            try:
                cat = ctm_info.categories.select_item(category_name.strip())
                cat_attr = cat.to_dict()
                diag = ctm_info.diagnostics.select_item(cat.offset +
                                                        int(number))
                diag_attr = diag.to_dict()
                if not unit.strip():  # unit may be empty in bpch
                    unit = diag_attr['unit']  # but not in tracerinfo
            except exceptions.SelectionMismatchError:
                diag = {'name': '', 'scale': 1}
                diag_attr = {}
                cat_attr = {}

            # parse metadata, get data or set a data proxy
            if dim2 == 1:
                data_shape = (dim0, dim1)  # 2D field
            else:
                data_shape = (dim0, dim1, dim2)
            from_file = os.path.abspath(filename)
            file_position = bpch_file.tell()
            if skip_data:
                bpch_file.skipline()
                data = BPCHDataProxy(data_shape, 'f', from_file,
                                     bpch_file.endian, file_position,
                                     diag['scale'], np.nan)
            else:
                data = np.array(bpch_file.readline('*f'))
                data = data.reshape((dim0, dim1, dim2), order='F')

            datablock = {
                'number': int(number),
                'name': diag['name'],
                'category': category_name.strip(),
                'times': (timeutil.tau2time(tau0), timeutil.tau2time(tau1)),
                'modelname': modelname.strip(),
                'center180': bool(center180),
                'halfpolar': bool(halfpolar),
                'origin': (dim3, dim4, dim5),
                'resolution': (res0, res1),
                'shape': data_shape,
                'loaded_from_file': from_file,
                'save_to_file': '',
                'file_position': file_position,
                'data': data,
                'unit': unit.strip(),
                'tracerinfo': diag_attr,
                'diaginfo': cat_attr
            }
            datablocks.append(datablock)

    return filetype, filetitle, datablocks
Example #4
0
 def load(self):
     with uff.FortranFile(self.path, 'rb', self.endian) as bpch_file:
         bpch_file.seek(self.file_position)
         data = np.array(bpch_file.readline('*f'))
         data = data.reshape(self.shape, order='F')
     return data * self.scale_factor