Ejemplo n.º 1
0
    def open_voxelplan(self, ctx_path):
        """
        Open a Voxelplan type CTX and possibly a VDX if one exists with the same basename.
        """

        model = self.model    # local object of plot_model
        pm = self.model.plot  # local object of plot_model

        # Get the CTX cubes first
        logger.debug("Open CTX {:s}".format(ctx_path))
        ctx = pt.CtxCube()
        ctx.read(ctx_path)

        # update model
        model.ctx = ctx
        pm.ctx = ctx

        # Point to center of slices for default plotting
        pm.xslice = int(ctx.dimx * 0.5)
        pm.yslice = int(ctx.dimy * 0.5)
        pm.zslice = int(ctx.dimz * 0.5)
        # TODO: we assume transversal view as start. fixme.
        pm.slice_pos_idx = int(ctx.dimz * 0.5)

        # show file basename in window title
        self.app.setWindowTitle("PyTRiPGUI - {}".format(ctx.basename))

        # Check if there is a VDX file with the same basename
        logger.debug("Check for VDX")
        from pytrip.util import TRiP98FilePath
        _b = TRiP98FilePath(ctx_path, ctx).basename
        _n = TRiP98FilePath(ctx_path, ctx).name
        vdx_path = ctx_path.replace(_n, _b) + '.vdx'

        logger.debug("Check if '{:s}' exists...".format(vdx_path))

        # If VDX is there, load it.
        if os.path.isfile(vdx_path):
            logger.debug("   Open '{:s}'".format(vdx_path))
            vdx = pt.VdxCube(self.model.ctx)
            vdx.read(vdx_path)

            # update model
            model.vdx = vdx
            pm.vdx = vdx

            # enable all VOIs to be plotted
            for voi in vdx.vois:
                pm.vois.append(voi)

        # add cube to the treeview<s
        self.tree.update_tree()

        # update the canvas
        self.plot.update_viewcanvas()
Ejemplo n.º 2
0
def load_data_cube(filename):
    """ Loads either a Dos or LET-cube.

    :params str filname: path to Dos or LET-cube.
    :returns: a DosCube or LETCube object and a str containing the path to the basename.
    """

    if not filename:
        logger.warn("Empty data cube filename")
        return None, None

    logger.info("Reading " + filename)

    d = None
    basename_cube = None

    # try to parse filename, first for LET then DOS cube
    # LET cube file have extension .dosemlet.dos, DOS cube files have extension .dos
    # this means that LET cube file can be interpreted as DOS cube file
    # it is then important to check first for LET cube

    let_path_helper = TRiP98FilePath(filename, pt.LETCube)
    dose_path_helper = TRiP98FilePath(filename, pt.DosCube)

    # check if LET cube type can be determinen by presence of suffix in a name (mlet, dosemlet)
    if let_path_helper.suffix is not None:
        cube_cls = let_path_helper.cube_type

    # check if DOS cube type can be determinen by presence of suffix in a name (phys, bio etc...)
    elif dose_path_helper.suffix is not None:
        cube_cls = dose_path_helper.cube_type

    # assume dose cube
    else:
        cube_cls = pt.DosCube

    d = cube_cls()  # creating cube object, reading file will be done later

    if d is not None:  # parsing successful, we can proceed to reading the file
        d.read(filename)
        logger.info("Data cube shape" + str(d.cube.shape))
        if isinstance(d, pt.DosCube):
            d *= 0.1  # convert %% to %

        dmax = d.cube.max()
        dmin = d.cube.min()
        logger.info("Data min, max values: {:g} {:g}".format(dmin, dmax))
    else:
        logger.warning("Filename " + filename +
                       " is neither valid DOS nor LET cube")

    basename_cube = d.basename

    return d, basename_cube
Ejemplo n.º 3
0
    def export_voxelplan(self, ctx_path):
        """
        Saves CTX and optional VDX data.
        Changes the ctx.basename to be in sync with the stem of the ctx_path. Same for optional VDX.
        """
        logger.debug("export_voxelplan() ctx_path={}".format(ctx_path))

        vdx_path = ctx_path  # hardcoded: VDX will always be stored along with CTX.
        if ".hed" in ctx_path:
            vdx_path = vdx_path.replace(".hed", ".vdx")
        elif ".ctx" in ctx_path:
            vdx_path = vdx_path.replace(".ctx", ".vdx")
        model = self.model
        ctx = self.model.ctx

        # If filename is not the default basename, then change the basename to the new stem of new path.
        from pytrip.util import TRiP98FilePath

        # os.path.basename(): see pytrip #456 https://github.com/pytrip/pytrip/issues/456
        _new_basename = TRiP98FilePath(os.path.basename(ctx_path),
                                       pt.CtxCube).basename
        if _new_basename != ctx.basename:
            logger.info("ctx.basename changed '{}' -> '{}'".format(
                ctx.basename, _new_basename))
            ctx.basename = _new_basename
            self.tree.update_tree()  # to trigger update of basenames in tree
            self.app.setWindowTitle("PyTRiPGUI - {}".format(
                ctx.basename))  # update window

        # Get the CTX cubes first
        logger.debug("Export CTX {:s}".format(ctx_path))
        ctx.write(ctx_path)

        # Check if there is a VDX file with the same basename
        if model.vdx:
            vdx = model.vdx
            # see pytrip #456 https://github.com/pytrip/pytrip/issues/456
            _new_basename = TRiP98FilePath(os.path.basename(vdx_path),
                                           pt.Cube).basename
            if _new_basename != vdx.basename:
                logger.info("vdx.basename changed '{}' -> '{}'".format(
                    vdx.basename, _new_basename))
                vdx.basename = _new_basename
                self.tree.update_tree(
                )  # to trigger update of basenames in tree
            logger.debug("Export VDX {:s}".format(vdx_path))
            vdx.write(vdx_path)
Ejemplo n.º 4
0
    def write(self, path):
        """Write the Cube and its header to a file with the filename 'path'.

        :param str path: path to header file, data file or basename (without extension)
        :returns: tuple header_path, datafile_path: paths to header file and datafiles where data was saved
        (may be different from input path if user provided a partial basename)
        """

        running_python2 = sys.version_info.major == 2
        path_string = isinstance(
            path,
            (str, bytes) if not running_python2 else basestring)  # NOQA: F821

        if path_string:
            header_path = self.header_file_name(path)
            datafile_path = self.data_file_name(path)

        elif len(path) == 2:
            header_path, datafile_path = path

            # security checks for header file
            # first check - validity of the path
            if not TRiP98FilePath(header_path, self).is_valid_header_path():
                logger.warning(
                    "Loading {:s} which doesn't look like valid header path".
                    format(header_path))

            # security checks for datafile path
            # first check - validity of the path
            if not TRiP98FilePath(datafile_path,
                                  self).is_valid_datafile_path():
                logger.warning(
                    "Loading {:s} which doesn't look like valid datafile path".
                    format(datafile_path))
        else:
            raise Exception(
                "More than two arguments provided as path variable to Cube.read method"
            )

        # finally write files
        self._write_trip_header(header_path)
        self._write_trip_data(datafile_path)

        return header_path, datafile_path
Ejemplo n.º 5
0
    def open_voxelplan(self, ctx_path):
        """
        Open a Voxelplan type CTX and possibly a VDX if one exists with the same basename.
        """

        model = self.model  # local object of plot_model

        # Get the CTX cubes first
        logger.debug("Open CTX {:s}".format(ctx_path))
        ctx = pt.CtxCube()
        ctx.read(ctx_path)

        # update model
        model.ctx = ctx
        self.model.one_plot.set_ctx(ctx)

        # show file basename in window title
        self.app.setWindowTitle("PyTRiPGUI - {}".format(ctx.basename))

        # Check if there is a VDX file with the same basename
        logger.debug("Check for VDX")
        from pytrip.util import TRiP98FilePath
        _d = TRiP98FilePath(
            ctx_path,
            ctx).dir_basename  # returns full path, but without suffix.
        vdx_path = _d + ".vdx"

        logger.debug("Check if '{:s}' exists...".format(vdx_path))

        # If VDX is there, load it.
        if os.path.isfile(vdx_path):
            logger.debug("   Open '{:s}'".format(vdx_path))
            vdx = pt.VdxCube(self.model.ctx)
            vdx.read(vdx_path)

            # update model
            model.vdx = vdx

        # update the canvas
        self.plot.update_viewcanvas()
Ejemplo n.º 6
0
    def read(self, path):
        """
        Reads both TRiP98 data and its associated header into the Cube object.

        Cube can be read providing a filename stripped of extension, i.e:
        >>> import pytrip as pt
        >>> c1 = pt.CtxCube()
        >>> c1.read("tests/res/TST003/tst003000")

        We can also read header file and data path which do not share common basename:
        >>> c2 = pt.CtxCube()
        >>> c2.read(("tests/res/TST003/tst003012.hed", "tests/res/TST003/tst003000.ctx.gz"))

        :param path: string or sequence of strings (length 2)
        :return:
        """

        # let us check if path is a string in a way python 2 and 3 will like it
        # based on https://stackoverflow.com/questions/4843173/how-to-check-if-type-of-a-variable-is-string
        running_python2 = sys.version_info.major == 2
        path_string = isinstance(
            path,
            (str, bytes) if not running_python2 else basestring)  # NOQA: F821

        # single argument of string type, i.e. filename without extension
        if path_string:
            self.basename = os.path.basename(
                TRiP98FilePath(path, self).basename)

            path_locator = TRiP98FileLocator(path, self)

            header_path = path_locator.header
            datafile_path = path_locator.datafile

            if not datafile_path or not header_path:
                raise FileNotFound(
                    "Loading {:s} failed, file not found".format(path))

        # tuple with path to header and datafile
        elif len(path) == 2:
            header_path, datafile_path = path

            # security checks for header file
            # first check - validity of the path
            if not TRiP98FilePath(header_path, self).is_valid_header_path():
                logger.warning(
                    "Loading {:s} which doesn't look like valid header path".
                    format(header_path))

            # second check - if file exists
            if not os.path.exists(header_path):
                header_path_locator = TRiP98FileLocator(header_path, self)
                if header_path_locator.header is not None:
                    logger.warning(
                        "Did you meant to load {:s}, instead of {:s} ?".format(
                            header_path_locator.header, header_path))
                raise FileNotFound(
                    "Loading {:s} failed, file not found".format(header_path))

            # security checks for datafile path
            # first check - validity of the path
            if not TRiP98FilePath(datafile_path,
                                  self).is_valid_datafile_path():
                logger.warning(
                    "Loading {:s} which doesn't look like valid datafile path".
                    format(datafile_path))

            # second check - if file exists
            if not os.path.exists(datafile_path):
                datafile_path_locator = TRiP98FileLocator(datafile_path, self)
                if datafile_path_locator.datafile is not None:
                    logger.warning(
                        "Did you meant to load {:s}, instead of {:s} ?".format(
                            datafile_path_locator.datafile, datafile_path))
                raise FileNotFound(
                    "Loading {:s} failed, file not found".format(
                        datafile_path))

            self.basename = ""  # TODO user may provide two completely different filenames for header and datafile
            # i.e. read( ("1.hed", "2.dos"), what about basename then ?

        else:
            raise Exception(
                "More than two arguments provided as path variable to Cube.read method"
            )

        # finally read files
        self._read_trip_header_file(header_path=header_path)
        self._read_trip_data_file(datafile_path=datafile_path,
                                  header_path=header_path)
Ejemplo n.º 7
0
 def data_file_name(cls, path_name):
     return TRiP98FilePath(path_name, cls).datafile
Ejemplo n.º 8
0
 def header_file_name(cls, path_name):
     return TRiP98FilePath(path_name, cls).header