diff --git a/AmpScan/AmpScanGUI.py b/AmpScan/AmpScanGUI.py index f7bc0dc4a07e4a039d1857f5d1f7274f132c0ff5..5c05520f9f50fad27d8c7f9561911114aed64a10 100644 --- a/AmpScan/AmpScanGUI.py +++ b/AmpScan/AmpScanGUI.py @@ -42,7 +42,7 @@ class AmpScanGUI(QMainWindow): self.renWin.renderActors([self.AmpObj.actor,]) self.AmpObj = AmpObject(self.fname[0], 'limb') self.AmpObj.addActor() - self.AmpObj.lp_smooth() +# self.AmpObj.lp_smooth() self.renWin.setnumViewports(1) self.renWin.setProjection() self.renWin.renderActors([self.AmpObj.actor,]) diff --git a/AmpScan/ampVis.py b/AmpScan/ampVis.py index 9cddf9acad4a382d46098212b144d21544e126b6..21fd2c80f14c170ad2bae737662bc05757394933 100644 --- a/AmpScan/ampVis.py +++ b/AmpScan/ampVis.py @@ -30,7 +30,7 @@ class vtkRenWin(vtk.vtkRenderWindow): # self.rens.append(vtkRender()) # self.rens[0].SetBackground(0.1, 0.2, 0.4) # self.rens[0].SetBackground(1.0,1.0,1.0) -# self.rens[0].SetActiveCamera(self.cams[0]) + self.rens[0].SetActiveCamera(self.cams[0]) # self.axes.append(vtk.vtkCubeAxesActor()) def renderActors(self, actors, viewport=0, diff --git a/AmpScan/fe.py b/AmpScan/fe.py index 5b6a16481ccdef71d38e0b60a77458ce4f4911e4..7d0084e95ee95bbf5693d5f52a0fa90c25aeb16c 100644 --- a/AmpScan/fe.py +++ b/AmpScan/fe.py @@ -55,15 +55,16 @@ class feMixin(object): """ np.gradient(self.values) - def addSurrogate(self, dat): + def addSurrogate(self, dat, theta=True): if isinstance(dat, str): self.surrogate = np.load(dat).item() else: self.surrogate = dat #surr = self.surrogate - #surr['sm_theta'] = 10 ** surr['sm_theta'] + if theta is True: + self.surrogate['sm_theta'] = 10 ** self.surrogate['sm_theta'] - def surrPred(self, x): + def surrPred(self, x, norm = True): surr = self.surrogate sh = surr['sm_U'].shape one = np.ones(sh[0]) @@ -76,6 +77,9 @@ class feMixin(object): theta = surr['sm_theta'][:,i] psi = np.exp(-np.sum(theta*np.power(np.abs(surr['X']-x), pl), axis=1)) eigs[i] = mu + np.dot(psi.T, feMixin.comp(u, feMixin.comp(u.T,y-one*mu))) + if norm is True: + yNorm = surr['sm_yRange'][:, i] + eigs[i] = (eigs[i] * (yNorm[1] - yNorm[0])) + yNorm[0] sf = (surr['pc_U'] * eigs).sum(axis=1) self.values[:] = surr['pc_mean'] + sf diff --git a/AmpScan/surrogateModelGUI_2.py b/AmpScan/surrogateModelGUI_2.py index 2df238a5ae71e15bbd20edc1d975400811689bc7..3c76a06439a40db1d20c8bc66a6f82434c491d4b 100644 --- a/AmpScan/surrogateModelGUI_2.py +++ b/AmpScan/surrogateModelGUI_2.py @@ -6,9 +6,12 @@ Created on Tue Oct 10 16:21:12 2017 """ import sys +import copy import os os.chdir('C:\\Local\\Documents (Local)\\Code\\AmpScan\\') import numpy as np +from scipy.special import binom +from scipy.interpolate import interp1d from AmpScan.core import AmpObject from AmpScan.ampVis import qtVtkWindow from PyQt5.QtWidgets import (QAction, QApplication, QGridLayout, @@ -21,8 +24,10 @@ from PyQt5.QtCore import pyqtSignal, Qt class GUI(QMainWindow): def __init__(self, parent=None): super(GUI, self).__init__() - self.points = np.zeros([5]) + self.points = np.zeros([3]) self.AmpObj = None + self.redFunc = None + self.scaleIdx = 0 self.mainWidget = QWidget() self.limbWidget = qtVtkWindow() self.limbRen = self.limbWidget._RenderWindow @@ -48,14 +53,47 @@ class GUI(QMainWindow): self.points[i] = s.value()/100 if self.AmpObj is None: return - self.AmpObj.surrPred(self.points[2:]) - self.AmpObj.actor.setValues(self.AmpObj.values) +# self.scale(self.points[:2]) + bezier = self.bSpline(self.points, self.socket.vert[:, 2]) + self.socket.values[:] = bezier[:, 1] * 6 + self.socket.actor.setValues(self.socket.values) + self.AmpObj.surrPred(self.points, norm=False) + self.AmpObj.actor.setValues(self.AmpObj.values) self.limbRen.Render() + self.socketRen.Render() + + def scale(self, var): + var = (var * 0.3) - 0.15 + cent = [85.93, 75.53, 0.0] + height = 150.0 + for p in [self.AmpObj, self.socket]: + if self.scaleIdx == 0: + p.nodes = copy.deepcopy(p.vert) + p.idx = p.nodes[:, 2] < height + nodes = p.nodes - cent + rad = np.sqrt(nodes[:,0]**2 + nodes[:,1]**2) + the = np.arctan2(nodes[:,1], nodes[:,0]) + bezier = self.bSpline([1, 1+var[1], 1+var[1]], nodes[p.idx, 2]) + rad[p.idx] = rad[p.idx] * bezier[:, 1] + x = rad * np.cos(the) + y = rad * np.sin(the) + nodes[:, 0] = x + cent[0] + nodes[:, 1] = y + cent[1] + # Length of the limb + nodes[p.idx, 2] += (nodes[p.idx, 2]-height) * var[0] + p.vert[:, :] = p.nodes + p.actor.points.Modified() + p.actor.setVert(p.vert) + self.scaleIdx = 1 + + def sliders(self): - variables = ['Residuum Length', 'Residuum Bulk', 'Proximal Reduction', - 'Mid Reduction', 'Distal Reduction'] - values = [50, 50, 0, 0, 0] +# variables = ['Proximal Reduction', 'Mid Reduction', 'Distal Reduction', +# 'Residuum Length', 'Residuum Bulk'] +# values = [0, 0, 0, 50, 50] + variables = ['Proximal Reduction', 'Mid Reduction', 'Distal Reduction'] + values = [0, 0, 0] groupBox = QGroupBox('Model Variables') box = QGridLayout() self.sliders = [] @@ -75,18 +113,33 @@ class GUI(QMainWindow): box.addWidget(self.sliders[-1], i, 1) groupBox.setLayout(box) return groupBox + + def bSpline(self, var, t): + weights = np.array([1.0, 5.0, 1.0]) + points = np.array([[0.0, var[2]], + [0.5, var[1]], + [1.0, var[0]]]) + zMin = t.min() + zRange = t.max() - zMin + t = (t - zMin)/zRange + num = np.zeros([t.shape[0], 2]) + dem = np.zeros([t.shape[0], 2]) + n = points.shape[0] - 1 + for (i, point), weight in zip(enumerate(points), weights): + biCoeff = binom(n, i) + num = num + ((biCoeff*t**i) * ((1-t)**(n-i)))[:, None] * point * weight + dem = dem + ((biCoeff*t**i) * ((1-t)**(n-i)))[:, None] * weight + return num/dem + def chooseOpenFile(self): self.fname = QFileDialog.getOpenFileName(self, 'Open file', filter="Surrogate Model (*.npy)") data = np.load(self.fname[0]).item() self.AmpObj = AmpObject(data['limb'], stype='FE') - self.AmpObj.centre() + #self.AmpObj.centre() self.AmpObj.addSurrogate(data['surr']) self.socket = AmpObject(data['socket']) - for i, s in enumerate(self.sliders): - self.points[i] = s.value()/100 - self.AmpObj.surrPred(self.points[2:]) c1 = [212.0, 221.0, 225.0] c2 = [31.0, 73.0, 125.0] CMap = np.c_[[np.linspace(st, en) for (st, en) in zip(c1, c2)]] @@ -94,13 +147,14 @@ class GUI(QMainWindow): self.AmpObj.addActor(CMap=CMap, bands = 10) self.AmpObj.actor.setNorm() self.AmpObj.actor.setScalarRange([0, 60]) - self.socket.addActor(CMap=CMap, bands = 10) + self.socket.addActor(CMap=CMap, bands = 128) self.socket.actor.setNorm() self.socket.actor.setScalarRange([0, 6]) - self.limbRen.renderActors([self.AmpObj.actor,], shading=False) + self.plotPress() + self.limbRen.renderActors([self.AmpObj.actor], shading=False) self.limbRen.setScalarBar(self.AmpObj.actor) self.limbRen.setView() - self.socketRen.renderActors([self.socket.actor,], shading=True) + self.socketRen.renderActors([self.socket.actor,], shading=False) self.socketRen.setScalarBar(self.socket.actor) self.socketRen.setView() diff --git a/AmpScan/tsbSocketDesign.py b/AmpScan/tsbSocketDesign.py index 7206f13b7955983ab1625f73956e515d1cae595d..ba54408bdb9492abaafb9314a4c1b265bf6639d7 100644 --- a/AmpScan/tsbSocketDesign.py +++ b/AmpScan/tsbSocketDesign.py @@ -24,9 +24,9 @@ class socketDesignMixin(object): def TSBSocket(self, B, stype=0): rho = np.sqrt(self.vert[:, 0]**2 + self.vert[:,1]**2) zRange = self.vert[:, 2].max() - self.vert[:, 2].min() - zB = (B[:, 0] * zRange) + data['vert'][:, 2].min() - perRed = np.interp(data['vert'][:, 2], zB, B[:, 1]) - data['values'] = rho * (perRed * 0.01) + zB = (B[:, 0] * zRange) + self.vert[:, 2].min() + perRed = np.interp(self.vert[:, 2], zB, B[:, 1]) + self.values[:] = rho * (perRed * 0.01) # def calcSpline(self, points):