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()
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
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)
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
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()
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)
def data_file_name(cls, path_name): return TRiP98FilePath(path_name, cls).datafile
def header_file_name(cls, path_name): return TRiP98FilePath(path_name, cls).header