def getTimepoint(self, n, onlyDims=0): """ Return the nth timepoint """ if not self.readers: self.getReadersFromFilenames() if self.is3DImage(): if not self.readers: raise Logging.GUIError( "Attempt to read bad timepoint", "Timepoint %d is not defined by the given filenames" % n) self.reader = self.readers[0] minZ = n * self.slicesPerTimepoint maxZ = (n + 1) * self.slicesPerTimepoint - 1 extract = vtk.vtkExtractVOI() extract.SetInput(self.reader.GetOutput()) extract.SetVOI(0, self.x - 1, 0, self.y - 1, minZ, maxZ) changeInfo = vtk.vtkImageChangeInformation() changeInfo.SetInput(extract.GetOutput()) changeInfo.SetOutputOrigin(0, 0, 0) changeInfo.SetExtentTranslation((0, 0, -minZ)) data = changeInfo.GetOutput() else: if n >= len(self.readers): n = 0 raise Logging.GUIError( "Attempt to read bad timepoint", "Timepoint %d is not defined by the given filenames" % n) self.reader = self.readers[n] data = self.reader.GetOutput() if not self.voxelsize: size = data.GetSpacing() x, y, z = [size.GetElement(x) for x in range(0, 3)] self.voxelsize = (x, y, z) print "Read voxel size", self.voxelsize if onlyDims: return return data
def checkImageDimensions(self, filenames): """ check that each image in the list has the same dimensions """ s = None hashStr = filenames[:] hashStr.sort() hashStr = str(hashStr) # check to see if there's already a result of the check for these filenames in the cache if hashStr in self.dimensionCheck: Logging.info("Using cached result for dimensions check: %s" % (str(self.dimensionCheck[hashStr]))) return self.dimensionCheck[hashStr] for file in filenames: if file not in self.imageDims: print "Trying to open", type(file) try: self.ext = file.split(".")[-1].upper() if self.ext == "TIF": self.ext = "TIFF" if self.ext == "JPG": self.ext = "JPEG" if self.ext == "VTI": reader = vtk.vtkXMLImageReader() else: reader = eval("vtk.vtk%sReader()" % self.ext) reader.SetFileName(file) reader.UpdateInformation() except IOError, ex: traceback.print_exc() raise Logging.GUIError("Cannot open image file", "Cannot open image file %s" % file) extent = reader.GetDataExtent() fSize = (extent[1], extent[3]) self.imageDims[file] = fSize else: fSize = self.imageDims[file] if s and fSize != s: x0, y0 = s x1, y1 = fSize self.dimensionCheck[hashStr] = False return 0 s = fSize fn = file
def setFilenames(self, filenames): """ set the filenames that will be read """ self.filenames = filenames if len(filenames) == 0: return if not self.dimensions: self.retrieveImageInfo(filenames[0]) if not self.checkImageDimensions(filenames): raise Logging.GUIError("Image dimensions do not match", \ "Some of the selected files have differing dimensions, \ and cannot be imported into the same dataset." ) self.getReadersFromFilenames() self.numberOfImages = len(filenames) if self.is3D: if self.readers: self.numberOfImages = 0 for rdr in self.readers: self.numberOfImages += rdr.GetNumberOfSubFiles()
def addSourceDataUnit(self, dataUnit, no_init=0): """ Adds 4D data to the unit together with channel-specific settings. @param dataUnit The SourceDataUnit to be added """ # If one or more SourceDataUnits have already been added, check that the # new SourceDataUnit has the same length as the previously added one(s): # if (self.getNumberOfTimepoints() != 0) and (self.getNumberOfTimepoints() != dataUnit.getNumberOfTimepoints()): # # XXX: Raise # print "Given dataunit had wrong length (%d != %d)" % (self.getNumberOfTimepoints(), dataUnit.getNumberOfTimepoints()) # Let's just use the smallest number of timepoints as a starting point if not self.getNumberOfTimepoints() or ( self.getNumberOfTimepoints() > dataUnit.getNumberOfTimepoints()): self.setNumberOfTimepoints(dataUnit.getNumberOfTimepoints()) if self.currentTimepoints and self.currentTimepoints != dataUnit.getNumberOfTimepoints( ): Dialogs.showwarning( None, "The datasets have different amount of timepoints: the lesser amount will be used.", "Warning: Number of timepoints differ") if self.currentSpacing and self.currentSpacing != dataUnit.getSpacing( ): raise Logging.GUIError("Dataset have different spacing", \ "The spacings of the datasets differ: %s and %s" \ % (self.getSpacing(), dataUnit.getSpacing())) if self.checkDimensions and self.currentDimensions and self.currentDimensions[:-1] != dataUnit.getDimensions( )[:-1]: raise Logging.GUIError("Datasets have different dimensions", \ "The dimensions of the datasets differ: %s and %s" \ %(self.currentDimensions, dataUnit.getDimensions())) self.currentDimensions = dataUnit.getDimensions() self.currentSpacing = dataUnit.getSpacing() self.currentTimepoints = dataUnit.getNumberOfTimepoints() # The DataUnit to be added must have a different name than the # previously added, or the dictionary won't work: count = len(self.sourceunits) self.sourceunits.append(dataUnit) # Create a settings object of correct type for dataunit # using the count as the index setting = self.getSettingsClass()(count) type = setting.get("Type") dataUnitSettings = dataUnit.getSettings() parser = dataUnit.getDataSource().getParser() if parser: setting.readFrom(parser) setting.set("Type", type) dataUnit.setSettings(setting) #print setting # Fetch correct settings for the dataunit from the datasource dataUnit.updateSettings() if not no_init: for unit in self.sourceunits: unit.getSettings().initialize(unit, count + 1, unit.getNumberOfTimepoints()) self.settings.initialize( self, count, self.sourceunits[0].getNumberOfTimepoints())
def getReadersFromFilenames(self): """ create the reader list from a given set of file names and parameters """ for i in self.readers: del i self.readers = [] if not self.filenames: raise Logging.GUIError("No files could be found", \ "For some reason, no files were listed to be imported.") files = self.filenames print "Determining readers from ", self.filenames isRGB = 1 self.ext = files[0].split(".")[-1].lower() dim = self.dimMapping[self.ext] # Initially flip the image if it's tiff, png or jpg. # In setVerticalFlip we negate the setting to have it set correctly. if self.ext.lower() in ["png", "jpg", "jpeg"]: self.flipVertically = True if self.ext in ["tif", "tiff"]: reader = vtkbxd.vtkExtTIFFReader() reader.SetFileName(files[0]) reader.UpdateInformation() if reader.GetNumberOfScalarComponents() >= 3: print "MODE IS RGB, IS AN RGB IMAGE" else: print "MODE ISN'T RGB, THEREFORE NOT RGB" isRGB = 0 rdr = self.getReaderByExtension(self.ext, isRGB) rdr.SetFileName(files[0]) if rdr.GetNumberOfSubFiles() > 1: dim = 3 self.isRGB = isRGB self.is3D = (dim == 3) dirName = os.path.dirname(files[0]) print "THERE ARE", self.slicesPerTimepoint, "SLICES PER TIMEPOINT" self.ext = files[0].split(".")[-1].lower() if dim == 3: totalFiles = len(files) for i, file in enumerate(files): rdr = self.getReaderByExtension(self.ext, isRGB) rdr.SetFileName(file) self.readers.append(rdr) return totalFiles = len(files) / self.slicesPerTimepoint imgAmnt = len(files) if totalFiles == 1: rdr = self.getReaderByExtension(self.ext, isRGB) arr = vtk.vtkStringArray() for fileName in files: arr.InsertNextValue(os.path.join(dirName, fileName)) rdr.SetFileNames(arr) self.readers.append(rdr) return if imgAmnt > 1: # If the pattern doesn't have %, then we just use # the given filenames and allocate them to timepoints # using slicesPerTimepoint slices per timepoint ntps = len(files) / self.slicesPerTimepoint filelst = files[:] # dirn #TODO: what was this? for tp in range(0, ntps): rdr = self.getReaderByExtension(self.ext, isRGB) arr = vtk.vtkStringArray() for i in range(0, self.slicesPerTimepoint): arr.InsertNextValue(filelst[0]) filelst = filelst[1:] rdr.SetFileNames(arr) rdr.SetDataExtent(0, self.x - 1, 0, self.y - 1, 0, self.slicesPerTimepoint - 1) rdr.SetDataSpacing(self.spacing) rdr.SetDataOrigin(0, 0, 0) self.readers.append(rdr) return elif imgAmnt == 1: # If only one file rdr = self.getReaderByExtension(self.ext, isRGB) rdr.SetDataExtent(0, self.x - 1, 0, self.y - 1, 0, self.slicesPerTimepoint - 1) rdr.SetDataSpacing(self.spacing) rdr.SetDataOrigin(0, 0, 0) rdr.SetFileName(files[0]) Logging.info("Reader = ", rdr, kw="io") self.readers.append(rdr)