Source code for febio_python.xplt.xplt_parser.read_xplt

from pathlib import Path
from typing import Tuple, Union
from febio_python.utils.log import console_log
from febio_python.core.enums import XPLT_TAGS as TAGS
from febio_python.core import (
    XpltMesh,
    States,
)
from ._binary_file_reader_helpers import search_block, read_bytes, get_file_size


def check_fileformat(bf, verbose):
    fformat = read_bytes(bf)
    if (TAGS.FEBIO.value == fformat):
        console_log('Correct FEBio format.', 2, verbose)
    else:
        raise ValueError(f"Input XPLIT file does not have the correct format. Expected: {TAGS.FEBIO.value}, received: {fformat}")


def check_fileversion(bf, verbose):
    version = read_bytes(bf)
    # return version
    if (version == TAGS.VERSION_2_5.value):
        console_log(f'Current spec version is: 2.5 -> {version}', 2, verbose)
        raise RuntimeError("XPLT version 2.5 is no longer supported.")
    elif (version == TAGS.VERSION_3_0.value):
        console_log(f'Current spec version is: 3.0 -> {version}', 2, verbose)
        return 3.0
    elif (version == 49):
        console_log(f'Current spec version is: 3.0 -> {version} | WARNING: Docs say version should be 8, but it is 49.', 2, verbose)
        return 3.0
    elif (version == 52):
        console_log(f'Current spec version is: 4.0 -> {version} | WARNING: Docs have not being released for spec 4.0. Using reader for spec 3.0', 2, verbose)
        return 4.0
    else:
        raise ValueError(
            f"Incorrect XPLIT file version: {version}, expected version: {TAGS.VERSION_2_5} or [{TAGS.VERSION_3_0} or 49]"
            # .format(version, int(TAGS.VERSION_2_5, base=16), int(TAGS.VERSION_3_0, base=16)))
        )


[docs] def read_xplt(xplit_filepath: Union[Path, str], verbose: int = 0) -> Tuple[XpltMesh, States]: """Reads a XPLT file and returns a XpltMesh and States object. Args: xplit_filepath (Union[Path, str]): _description_ verbose (int, optional): _description_. Defaults to 0. Returns: Tuple[XpltMesh, States]: _description_ """ xplit_filepath = Path(xplit_filepath) if not xplit_filepath.exists(): raise FileNotFoundError(f"File not found: {xplit_filepath}") # open binary file with open(xplit_filepath, "rb") as bf: # get file size and check if its not empty filesize = get_file_size(bf) if filesize == 0: raise ValueError("Input xplit file size is zero. Please, check file.") # check if file format meets requirement check_fileformat(bf, verbose) console_log("Checking filer version", 1, verbose, header=True) # move cursor to "ROOT" search_block(bf, TAGS.ROOT, verbose=verbose) # move cursor to "HEADER" search_block(bf, TAGS.HEADER, verbose=verbose) # move cursor to "HDR_VERSION" -> feb file version search_block(bf, TAGS.HDR_VERSION, verbose=verbose) version = check_fileversion(bf, verbose) console_log(f"File version: {version}", 2, verbose) if version == 3.0: from ._spec_30 import read_spec30 return read_spec30(xplit_filepath, verbose=verbose) elif version == 4.0: from ._spec_40 import read_spec40 return read_spec40(xplit_filepath, verbose=verbose) else: raise ValueError(f"XPLT file version not supported: {version}" "We currently only support version 3.0 and 4.0." "NOTE: version 4.0 is not fully supported yet.")