def __init__(self, parent = None):
	
		QtGui.QMainWindow.__init__(self, parent)
		self.ui = Ui_MainWindow()
		
		self.renWinList = []
		   
		# data_file = askopenfilename()
		data_file = '/Users/emonson/Data/Fodava/EMoGWDataSets/mnist1_5c_20100324.mat'
# 		self.openFilesDefaultPath = QtCore.QDir.homePath()
# 		data_file = QtGui.QFileDialog.getOpenFileName(self,
# 				"Load Saved Matlab File", 
# 				self.openFilesDefaultPath,
# 				"All Files (*);;Matlab Files (*.mat)")
		
		# DataSource loads .mat file and can generate data from it for other views
		self.ds = DataSource(str(data_file))
		
		# All view classes have access to an instance of that data source for internal queries
		# Note that the only view which will pull and display data right away is the icicle view
		#  the other views need to be able to initialize without any data and only pull and show
		#  upon the first AnnotationChanged event...
		
		# View #0 -- Icicle View
		# Set up a 2D scene, add an XY chart to it
		self.chartView = vtk.vtkContextView()
		self.chartView.GetRenderer().SetBackground(1.0, 1.0, 1.0)
		self.renWinList.append(self.chartView.GetRenderWindow())

		self.chart = vtkvtg.vtkMyChartXY()
		self.chartView.GetScene().AddItem(self.chart)

		# View #1 -- AxisImageView
		self.axisView = vtk.vtkContextView()
		self.axisView.GetRenderer().SetBackground(1.0, 1.0, 1.0)
		self.renWinList.append(self.axisView.GetRenderWindow())

		self.ai = vtkvtg.vtkAxisImageItem()
		self.axisView.GetScene().AddItem(self.ai)
		
		# Set up all the render windows in the GUI
		self.ui.setupUi(self, self.renWinList)
		
		# Now need to get all the interactors working properly
		# XY
		style0 = vtk.vtkInteractorStyleRubberBand2D()
		self.chartView.GetInteractor().SetInteractorStyle(style0)
		self.chartView.GetScene().SetInteractorStyle(style0)

		# Axis images
		style1 = vtk.vtkInteractorStyleRubberBand2D()
		self.axisView.GetInteractor().SetInteractorStyle(style1)
		self.axisView.GetScene().SetInteractorStyle(style1)

		# Set sizes for veritcal splitters
		self.ui.splitter.setSizes([200,400])		
		
		# Connect signals and slots
		QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL("triggered()"), self.fileExit)

		
		# CORE setting up chart and axis images
		test_id = 68
		self.table = self.ds.GetNodeOneScaleCoeffTable(test_id)
		
		line1 = vtkvtg.vtkMyPlotPoints()
		# line1.DebugOn()
		self.chart.AddPlot(line1)		# POINTS
		line1.SetInput(self.table, 0, 1)
		line1.SetMarkerStyle(2)
		line1.SetColor(0, 0, 0, 255)
		
		# Tooltip image stack will now be owned by the tooltip, so need to do that differently... 
		id_list = self.ds.PIN[test_id]
		image_stack = self.ds.GetProjectedImages(id_list)
		self.chart.SetTooltipImageStack(image_stack)
		self.chart.SetTooltipShowImage(True)
		# self.chart.SetTooltipImageScalingFactor(2.0)
		self.chart.SetTooltipImageTargetSize(40)
		
		axis_images = self.ds.GetNodeBasisImages(test_id)
		center_image = self.ds.GetNodeCenterImage(test_id)
		self.ai.SetAxisImagesHorizontal()
		self.ai.SetChartXY(self.chart)
		self.ai.SetChartXYView(self.chartView)
		self.ai.SetAxisImageStack(axis_images)
		self.ai.SetCenterImage(center_image)
		
		# Set up annotation link which will carry indices to parallel coordinates chart
		# for highlighting outside selections (e.g. back from image_flow)
		# This needs to carry indices, while image_flow link outputs pedigree ids
		# so conversion happens in HighlightSelectionCallback
# 		data_col_idxs = vtk.vtkAnnotationLink()
# 		data_col_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
# 		data_col_idxs.GetCurrentSelection().GetNode(0).SetContentType(4)   # 2 = PedigreeIds, 4 = Indices
# 		self.chart.SetDataColumnsLink(data_col_idxs)
# 		self.ai.SetDataColumnsLink(data_col_idxs)

		# Create a annotation link to access selection in XY chart
		annotationLink = vtk.vtkAnnotationLink()
		annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
		annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4)   # Indices
		# Connect the annotation link to the parallel coordinates representation
		self.chart.SetAnnotationLink(annotationLink)
		self.chart.GetAnnotationLink().AddObserver("AnnotationChangedEvent", self.IcicleSelectionCallback)

		# Set up annotation link which will carry indices to parallel coordinates chart
		# for highlighting outside selections (e.g. back from image_flow)
		# This needs to carry indices, while image_flow link outputs pedigree ids
		# so conversion happens in HighlightSelectionCallback
		highlight_link_idxs = vtk.vtkAnnotationLink()
		highlight_link_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
		highlight_link_idxs.GetCurrentSelection().GetNode(0).SetContentType(4)   # 2 = PedigreeIds, 4 = Indices
		self.chart.SetHighlightLink(highlight_link_idxs)
		
		# Fill selection link with dummy IDs
		id_array = N.array([0],dtype='int64')
		id_list = VN.numpy_to_vtkIdTypeArray(id_array, deep=True)
		highlight_link_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(id_list)
		highlight_link_idxs.InvokeEvent("AnnotationChangedEvent")

# 		self.updater = vtk.vtkViewUpdater()
# 		self.updater.AddAnnotationLink(data_col_idxs)
# 		self.updater.AddView(self.axisView)
# 		self.updater.AddView(self.chartView)
		
# 		col_array = N.array([0,1],dtype='int64')
# 		col_vtk = VN.numpy_to_vtkIdTypeArray(col_array, deep=True)
# 		data_col_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(col_vtk)
# 		data_col_idxs.InvokeEvent("AnnotationChangedEvent")
		
		self.chart.RecalculateBounds()

		# Only need to Start() interactor for one view
		# self.pc_class.GetView().GetInteractor().Start()
		# Shouldn't have to do this render...
		for rw in self.renWinList:
			rw.Render()
Exemple #2
0
	def InputSelectionCallback(self, caller, event):
		"""This is the callback that tracks changes in the icicle view and
		sets the input table for the parallel coordinates chart accordingly.
		Note: This can only handle a single input nodeID for now..."""

		annSel = caller.GetCurrentSelection()
		# Note: When selection is cleared, the current selection does NOT contain any nodes
		if annSel.GetNumberOfNodes() > 0:
			idxVtk = annSel.GetNode(0).GetSelectionList()
			idxArr = VN.vtk_to_numpy(idxVtk)
			print "ice input to XY ", idxArr

			# Here is where I'm limiting the selection to _one_ nodeID for now...
			node_id = idxArr[0]

			# If this is the same icicle node as before
			same_ice_node = False
			if node_id == self.input_link_idx:
				same_ice_node = True

			self.table = self.ds.GetNodeOneScaleCoeffTable(node_id)
			id_list = self.ds.PointsInNet[node_id]	# Directly accessing member variable
			self.axis_images = self.ds.GetNodeBasisImages(node_id, True)
			if not same_ice_node:
				if self.ds.hasDocTitles:
					self.text_stack = self.ds.GetDocTitles(id_list)
				else:
					self.image_stack = self.ds.GetProjectedImages(id_list, True, True)
				self.center_image = self.ds.GetNodeCenterImage(node_id, True)

			# Get the axis image XY indices in case resetting to those values
			# and the number of dimensions has changed, and xI or yI are over the limit
			xI = self.ai.GetXAxisIndex()
			yI = self.ai.GetYAxisIndex()
			if yI > xI:
				y_bigger = 1
			else:
				y_bigger = 0

			# Check whether they're out of range for the new data
			(dX,dY,dZ) = self.axis_images.GetDimensions()
			max_dim = dZ - 1
			if yI > max_dim:
				yI = max_dim
			if xI > max_dim:
				xI = max_dim
			if xI == yI:
				if y_bigger:
					xI = yI-1
				else:
					yI = xI-1
			if xI < 0:
				xI = 0
			if yI < 0:
				yI = 0
				
			# Deal with the case where go from 1D to mutipleD on wav/scal switchover
			if (max_dim > 0) and (xI == 0) and (yI == 0):
				yI = 1
			
			# DEBUG
			# print "__ Axis image max_dim, xI, yI: ", max_dim, xI, yI

			self.chart.ClearPlots()
			self.ai.ClearAxisImages()

			line1 = vtkvtg.vtkMyPlotPoints()
			
			# Count number of non-_ids column names
			num_real_cols = len([self.table.GetColumnName(ii) 
			                    for ii in range(self.table.GetNumberOfColumns()) 
			                    if not self.table.GetColumnName(ii).endswith('_ids')])
			if (num_real_cols > 1):
				line1.SetInput(self.table, 0, 1)
			else:
				line1.SetInput(self.table, 0, 0)
			line1.SetMarkerStyle(vtkvtg.vtkMyPlotPoints.CIRCLE)

			# Adding plot must happen after plot.SetInput or rendering crashes...
			self.chart.AddPlot(line1)		# POINTS
			self.SetColorByArray(self.color_array_name)


			# Need to set the image stack for the plot which will get resliced
			if not same_ice_node:
				if self.ds.hasDocTitles:
					self.chart.GetTooltip().SetTextStack(self.text_stack)
				else:
					self.chart.SetTooltipImageStack(self.image_stack)
			# self.chart.SetTooltipShowImage(True)
			# self.chart.SetTooltipImageScalingFactor(0.5)
			self.chart.SetTooltipImageTargetSize(60)
			self.chart.Update()

			# If this is the same icicle node as before, then reset to original XY indices
			# before view is updated
			if same_ice_node:
				self.chart.SetPlotColumnIndices(xI,yI)

			self.ai.SetAxisImagesHorizontal()
			self.ai.SetAxisImageStack(self.axis_images)
			if not same_ice_node:
				self.ai.SetCenterImage(self.center_image)

			# If this is the same icicle node as before, then reset to original XY indices
			# before view is updated
			if same_ice_node:
				self.ai.SetAxisIndices(xI,yI)

			self.ai.Update()

			self.PedIdToIndexSelection()

			# self.chartView.ResetCamera()
			self.input_link_idx = node_id
			self.chartView.Render()
			self.axisView.Render()

		else:
			self.chart.ClearPlots()
			self.table = None
			# self.chart.Update()
			# self.chartView.ResetCamera()
			self.chartView.Render()

			self.ai.ClearAxisImages()
			self.axisView.Render()
	def __init__(self, parent = None):
	
		QtGui.QMainWindow.__init__(self, parent)
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)
		   
		# Set up a 2D scene (later we'll add a pcoords chart to it)
		self.view = vtk.vtkContextView()
		# self.view.GetRenderer().SetBackground(1.0, 1.0, 1.0)
		
		# // QVTKWidget *widget = new QVTKWidget;
		# // vtkContextView *view = vtkContextView::New();
		# // view->SetInteractor(widget->GetInteractor());
		# // widget->SetRenderWindow(view->GetRenderWindow());

		# Necessary for RenderView types
		self.view.SetInteractor(self.ui.vtkWidget.GetInteractor())
		self.ui.vtkWidget.SetRenderWindow(self.view.GetRenderWindow())

		data_file = '/Users/emonson/Data/Fodava/EMoGWDataSets/mnist12_1k_20101119.mat'
		
		# DataSource loads .mat file and can generate data from it for other views
		ds = DataSource(data_file)

		# Testing my custom chart class which has image hover tooltips
		chart = vtkvtg.vtkMyChartXY()
		chart.SetActionToButton(vtk.vtkChart.PAN, 2)
		chart.SetActionToButton(vtk.vtkChart.ZOOM, 4)
		chart.SetActionToButton(vtk.vtkChart.SELECT, 1)
		self.view.GetScene().AddItem(chart)
		
		# Create a annotation link to access selection in parallel coordinates view
		annotationLink = vtk.vtkAnnotationLink()
		# If you don't set the FieldType explicitly it ends up as UNKNOWN (as of 21 Feb 2010)
		# See vtkSelectionNode doc for field and content type enum values
		annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
		annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4)   # Indices
		# Connect the annotation link to the parallel coordinates representation
		chart.SetAnnotationLink(annotationLink)
		
		test_id = 3
		table = ds.GetNodeOneScaleCoeffTable(test_id)
		
		chart.ClearPlots()
		
		line1 = vtkvtg.vtkMyPlotPoints()
		chart.AddPlot(line1)		# POINTS
		line1.SetInput(table, 0, 1)
		line1.SetMarkerStyle(2)
		line1.SetColor(0, 0, 0, 255)
		
		# Tooltip image stack will now be owned by the tooltip, so need to do that differently... 
		id_list = ds.PointsInNet[test_id]
		image_stack = ds.GetProjectedImages(id_list)
		chart.SetTooltipImageStack(image_stack)
		chart.SetTooltipShowImage(True)
		# chart.SetTooltipImageScalingFactor(2.0)
		chart.SetTooltipImageTargetSize(40)
		
		# Set up annotation link which will carry indices to parallel coordinates chart
		# for highlighting outside selections (e.g. back from image_flow)
		# This needs to carry indices, while image_flow link outputs pedigree ids
		# so conversion happens in HighlightSelectionCallback
		highlight_link_idxs = vtk.vtkAnnotationLink()
		highlight_link_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
		highlight_link_idxs.GetCurrentSelection().GetNode(0).SetContentType(4)   # 2 = PedigreeIds, 4 = Indices
		chart.SetHighlightLink(highlight_link_idxs)
		
		# Finally render the scene and compare the image to a reference image
		# view.GetRenderWindow().SetMultiSamples(0)
		
		annotationLink.AddObserver("AnnotationChangedEvent", self.selectionCallback)
		
		# view.ResetCamera()
		# view.Render()
		
		# Fill selection link with dummy IDs
		id_array = N.array([0],dtype='int64')
		id_list = VN.numpy_to_vtkIdTypeArray(id_array)
		highlight_link_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(id_list)
		highlight_link_idxs.InvokeEvent("AnnotationChangedEvent")
		
		# Set up annotation link which will carry indices to parallel coordinates chart
		# for highlighting outside selections (e.g. back from image_flow)
		# This needs to carry indices, while image_flow link outputs pedigree ids
		# so conversion happens in HighlightSelectionCallback
		data_col_idxs = vtk.vtkAnnotationLink()
		data_col_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
		data_col_idxs.GetCurrentSelection().GetNode(0).SetContentType(4)   # 2 = PedigreeIds, 4 = Indices
		chart.SetDataColumnsLink(data_col_idxs)
		# Fill selection link with dummy IDs
		col_array = N.array([1,2],dtype='int64')
		col_list = VN.numpy_to_vtkIdTypeArray(col_array)
		data_col_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(col_list)
		data_col_idxs.InvokeEvent("AnnotationChangedEvent")
		
		# Start interaction event loop
		self.ui.vtkWidget.show()
# Create a annotation link to access selection in parallel coordinates view
annotationLink = vtk.vtkAnnotationLink()
# If you don't set the FieldType explicitly it ends up as UNKNOWN (as of 21 Feb 2010)
# See vtkSelectionNode doc for field and content type enum values
annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1)     # Point
annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4)   # Indices
# Connect the annotation link to the parallel coordinates representation
chart.SetAnnotationLink(annotationLink)

test_id = 3
table = ds.GetNodeOneScaleCoeffTable(test_id)

chart.ClearPlots()

line1 = vtkvtg.vtkMyPlotPoints()
chart.AddPlot(line1)		# POINTS
line1.SetInput(table, 0, 1)
line1.SetMarkerStyle(2)
line1.SetColor(0, 0, 0, 255)

# Tooltip image stack will now be owned by the tooltip, so need to do that differently... 
id_list = ds.PointsInNet[test_id]
image_stack = ds.GetProjectedImages(id_list)

# DEBUG
writer = vtk.vtkXMLImageDataWriter()
writer.SetFileName('out.vti')
writer.SetInput(image_stack)
writer.Write()