Package empro :: Package toolkit :: Package analysis :: Module results_overview
[frames] | no frames]

Source Code for Module empro.toolkit.analysis.results_overview

  1  # Copyright 1983-2019 Keysight Technologies, Inc, Keysight Confidential 
  2  from empro.gui import SimpleDialog, TableView, Cancel, ComboBox, Label, GridLayout,TabWidget 
  3  import string 
  4  from string import Template 
  5  import os 
  6   
  7  from empro.toolkit import _printexception 
  8  from empro.toolkit import Bunch 
 15   
16 @_printexception 17 -def _openDocxFile( file ):
18 import webbrowser 19 webbrowser.open( file )
20
21 -class ResultsOverview(object):
22 @_printexception
23 - def __init__(self, resultsDiff):
24 # dialog 25 import empro.gui 26 import empro 27 self.dialog = SimpleDialog(0) 28 #self.dialog.setButtonText(Cancel,'Close') 29 self._showDifference = False 30 self._temperatureFormat = "%4.1f" 31 self._voltageFormat = "%4.4f" 32 self._milliVoltageFormat = "%2.2f" 33 self._currentDensityFormat = "%5.1f" 34 self._epsRFormat = "%3.1f" 35 self._lossTangentFormat = "%4.3f" 36 self._conductivityFormat = "%7.0f S/m" 37 38 if isinstance(resultsDiff, empro.toolkit.analysis.dc.results.DCResults): 39 self.dialog.title = "DC Results Overview - " + resultsDiff.resultName 40 elif isinstance(resultsDiff, empro.toolkit.analysis.dc.results.DCResultsDiff): 41 self.dialog.title = "DC Results Overview - " + resultsDiff.resultNames[0] + " vs " + resultsDiff.resultNames[1] 42 self._showDifference = True 43 self.dialog.resize(860, 600) 44 self.dialog.onFinished = self.onFinished 45 self.results = resultsDiff 46 self.tableInfo = [] 47 self.orgTableInfo = [] 48 self.acceptFlag = 0 49 self.alwaysExport = False 50 self.path = "" 51 self._viaHighlightSegment = "sipi_overview_via_highlight" 52 self._viaHighlightSegmentLines = "sipi_overview_via_highlight_lines" 53 self._viaHighlightColor = (1.0, 0.25, 0.25, 1.0) 54 self._pinResultHighlightSegment = "sipi_overview_pin_result_highlight" 55 self._pinResultHighlightColor=(255,0,0) 56 self._passIcon = empro.gui.Icon(":/application/Valid.ico") 57 self._failIcon = empro.gui.Icon(":/application/Invalid.ico") 58 self.tabWidget = TabWidget() 59 w = empro.gui.Widget() 60 self.powerGraphTabId, self.sinksTabId, self.vrmsTabId, self.thermalComponentsTabId, self.layersTabId, self.pinsTabId, self.viasTabId, self.reportsTabId = range(8) 61 self.tabWidget.insertTab(self.powerGraphTabId, self._powerGraphTab(), "Power Graph") 62 self.tabWidget.insertTab(self.sinksTabId, self._sinkTab(), "Sinks") 63 self.tabWidget.insertTab(self.vrmsTabId, self._vrmsTab(), "VRMs") 64 self.tabWidget.insertTab(self.thermalComponentsTabId, self._thermalComponentsTab(), "Thermal Components") 65 self.tabWidget.insertTab(self.layersTabId, self._layersTab(), "Layers") 66 self.tabWidget.insertTab(self.pinsTabId, self._pinsTab(), "Pins") 67 self.tabWidget.insertTab(self.viasTabId, self._viasTab(), "Vias") 68 self.tabWidget.onCurrentChanged = self._tabChanged 69 70 self._containerWidget = self.dialog.mainWidget() 71 self._menuBar = empro.gui.MenuBar() 72 self._m = self._menuBar.addMenu("File") 73 self._mo = self._menuBar.addAction("Options...") 74 self._optionsActions = [] 75 self._optionsActions.append(self._mo) 76 self._optionsActions[-1].onTriggered = lambda x:self._plotOptions() 77 self._compareActions = [] 78 self._exportActions = [] 79 if not self._showDifference: 80 self._compareMenu = self._m.addMenu("Compare to") 81 for setup in empro.activeProject.analyses: 82 if self.results.resultName!=setup.name and setup.analysisType in [empro.analysis.Analysis.THAnalysisType,empro.analysis.Analysis.ETHAnalysisType,empro.analysis.Analysis.DCAnalysisType]: 83 self._compareActions.append(self._compareMenu.addAction(setup.name)) 84 self._compareActions[-1].onTriggered = lambda x,y=setup:self._compareTo(y) 85 86 self._exportMenu = self._m.addMenu("Export") 87 self._exportActions.append(self._exportMenu.addAction("HTML...")) 88 self._exportActions[-1].onTriggered = lambda x:self._exportToHtml() 89 self._exportActions.append(self._exportMenu.addAction("DocX...")) 90 #self._exportActions[-1].enabled = True 91 self._exportActions[-1].onTriggered = lambda x:self._exportToDocX() 92 93 #self._menuBar.addStyleSheet('background: red') 94 self.dialog.layout.add(self._menuBar) 95 96 self.dialog.layout.add(self.tabWidget) 97 98 self.geometryViewExportedForReporting = False 99 self.tempimgfilename = None 100 # set window flags 101 self.dialog.windowFlags = empro.gui.WF_Window 102 self.dialog.windowFlags &= ~empro.gui.WF_WindowStaysOnTopHint 103 104 import empro 105 celsius = empro.units.unitByAbbreviation("degC") 106 if self._showDifference: 107 celsius = empro.units.unitByAbbreviation("K") 108 109 index = 0 110 111 zSortedLayerNames = [ (k,v['zMax'],v['zMin']) for (k,v) in self.results.layerStatistics.iteritems()] 112 zSortedLayerNames = sorted(zSortedLayerNames, key=lambda x:(-x[2],-x[1])) 113 114 115 for layer in zSortedLayerNames: 116 layerName = layer[0] 117 layerStats = self.results.layerStatistics[layerName] 118 row = [layerName, self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMin"]), self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMax"]), layerStats["currentMin"]*1e-6,layerStats["currentMax"]*1e-6,layerStats["voltageMin"],layerStats["voltageMax"]] 119 self._layersTable.setRow(index, row) 120 index += 1 121 122 self._hasAtLeastOneSenseLine = False 123 self._hasAtLeastOneSwitch = False 124 for vrm in self.results.vrms: 125 if vrm.senseVoltage is not None: 126 self._hasAtLeastOneSenseLine = True 127 if vrm.sourceType != 'PackagedVrm': 128 self._hasAtLeastOneSwitch = True 129 if self._hasAtLeastOneSenseLine and self._hasAtLeastOneSwitch: 130 break 131 132 for index, vrm in enumerate(self.results.vrms): 133 row = [vrm.name, vrm.sourceVoltage, vrm.outputVoltage ,abs(vrm.outputCurrent), abs(vrm.outputCurrent*vrm.outputVoltage), vrm.tolerance, self._milliVoltageFormat % (vrm.margin*1000.0)] 134 if self._hasAtLeastOneSenseLine and (self.results.resultAnalysisType == 1 or self.results.resultAnalysisType == 6): 135 voltage_diff = None 136 if vrm.senseVoltage is not None: 137 voltage_diff = self._milliVoltageFormat % ((vrm.senseVoltage-vrm.senseportVoltage)*1000.0) 138 row.append(vrm.senseVoltage) 139 row.append(vrm.senseportVoltage) 140 row.append(voltage_diff) 141 if self._hasAtLeastOneSwitch and (self.results.resultAnalysisType == 1 or self.results.resultAnalysisType == 6): 142 row.append(vrm.inputVoltage) 143 row.append(abs(vrm.upSwitchBunch.current) if vrm.upSwitchBunch else None) 144 row.append(abs(-vrm.lowSwitchBunch.current) if vrm.lowSwitchBunch else None) 145 row.append(abs(-vrm.inductorBunch.current) if vrm.inductorBunch else None) 146 if vrm.switchOutputVoltage and vrm.switchOutputCurrent: 147 row[2] = vrm.switchOutputVoltage 148 row[3] = abs(vrm.switchOutputCurrent) 149 row[4] = abs(vrm.switchOutputVoltage*vrm.switchOutputCurrent) 150 if not self._showDifference: 151 row.append(vrm.result) 152 self._vrmsTable.setRow(index, row) 153 if not self._showDifference: 154 icon = {True:self._failIcon, False:self._passIcon}["fail" in vrm.result.lower()] 155 self._vrmsTable.setDecoration(index,0, icon) 156 if "fail" in vrm.result.lower(): 157 for i in range(len(row)): 158 self._vrmsTable.setData(index, i, (0.9,0.5,0.5,1.0),8) 159 160 161 for index, sink in enumerate(self.results.sinks): 162 irDrop = sink.vrmOutputVoltage-sink.inputVoltage 163 deltaV = sink.vrmVoltage - sink.inputVoltage 164 deltaVg = sink.maxVoltageGroundPins 165 deltaVp = sink.vrmVoltage-sink.minVoltagePowerPins 166 row = [sink.name, sink.vrmVoltage, sink.sourceCurrent, sink.inputVoltage,abs(sink.sourceCurrent*sink.inputVoltage), self._milliVoltageFormat % (irDrop*1000.0), self._milliVoltageFormat % (deltaV*1000.0), self._milliVoltageFormat % (deltaVp*1000.0), self._milliVoltageFormat % (deltaVg*1000.0), sink.tolerance, self._milliVoltageFormat % (sink.margin*1000.0),sink.resistance*1000.0] 167 if not self._showDifference: 168 row.append(sink.result) 169 self._sinksTable.setRow(index, row) 170 if not self._showDifference: 171 icon = {True:self._failIcon, False:self._passIcon}["fail" in sink.result.lower()] 172 self._sinksTable.setDecoration(index,0, icon) 173 if "fail" in sink.result.lower(): 174 for i in range(len(row)): 175 self._sinksTable.setData(index, i, (0.9,0.5,0.5,1.0),8) 176 177 178 for index, source in enumerate(self.results.thermalComponents): 179 if hasattr(source,'heatDie'): 180 row = [source.name, source.heatDie, source.heatBoard, source.heatCase] 181 else: 182 row = [source.name, source.heat, '---', '---'] 183 if hasattr(source,"temperature"): 184 row += [self._temperatureFormat % celsius.fromReferenceUnits(source.temperature), "---","---","---", source.bareBoardThermalResistance] 185 else: 186 row += ["---", self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureBoard), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureDie), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureCase),source.bareBoardThermalResistance] 187 self._thermalComponentsTable.setRow(index, row) 188 189 if not self.results.vrms or not self.results.sinks: 190 self.tabWidget.setTabEnabled(self.powerGraphTabId,False) 191 if not self.results.sinks: 192 self.tabWidget.setTabEnabled(self.sinksTabId,False) 193 if not self.results.vrms: 194 self.tabWidget.setTabEnabled(self.vrmsTabId,False) 195 if not self.results.pins: 196 self.tabWidget.setTabEnabled(self.pinsTabId,False) 197 if not self.results.thermalComponents: 198 self.tabWidget.setTabEnabled(self.thermalComponentsTabId,False) 199 200 realIndex = 0 201 instanceCandidates = set() 202 for index, pin in enumerate(self.results.pins): 203 if pin.name!="---": 204 instanceName = "" 205 tokens = pin.name.split(".") 206 if len(tokens)==2: 207 instanceName=tokens[0] 208 instanceCandidates.add(instanceName) 209 row= [pin.name,pin.netName,pin.netType,pin.voltage,pin.current, celsius.fromReferenceUnits(pin.temperature)] 210 self._pinsTable.setRow(realIndex, row) 211 realIndex += 1 212 instanceCandidatesList = list(instanceCandidates) 213 instanceWithDesignatorList = [] 214 for part in empro.activeProject.geometry().flatList(True): 215 if isinstance(part, empro.geometry.OaLayout): 216 for index in range(part._instanceCount()): 217 inst = part._instance(index) 218 if inst.name in instanceCandidates: 219 instanceWithDesignatorList.append(inst.name + " ( " + inst.libraryName + ":" + inst.cellName + " )") 220 self._instanceFilter.clear() 221 self._instanceFilter.addItem("All") 222 self._instanceFilter.addItem("Top Level Pins") 223 for instName in instanceWithDesignatorList: 224 self._instanceFilter.addItem(instName) 225 226 # fix for non-visible table content on Linux 227 deltaSymbol = "" 228 if self._showDifference: 229 deltaSymbol = u"\u0394 " 230 231 232 self._layersTable.headers = ["Layer", deltaSymbol + u"Min T\n [\u00B0C]",deltaSymbol+u"Max T\n[\u00B0C]", deltaSymbol+"Min Current\nDensity [A/mm**2]", deltaSymbol+"Max Current\nDensity [A/mm**2]",deltaSymbol+"Min\nVoltage [V]", deltaSymbol+"Max\nVoltage [V]"] 233 self._layersTable.resizeColumnsToContents() 234 sinkHeaders = ["Name", deltaSymbol+"VRM\nVoltage [V]",deltaSymbol+"Input\nCurrent [A]", deltaSymbol+"Input\n Voltage [V]", deltaSymbol+"Input\nPower [W]", deltaSymbol+"IR Drop\n[mV]", u"\u0394V\n[mV]", u"\u0394Vp\n[mV]", u"\u0394Vg\n[mV]", deltaSymbol+"Tolerance", deltaSymbol+"Margin\n[mV]", deltaSymbol+"Resistance\n [mOhm]"] 235 self._sinksTable.headers = sinkHeaders 236 self._sinksTable.columnSizeHints = [(x,36) for x in [100,75,75,75,75,75,50,50,60,60]] 237 self._sinksTable.resizeColumnsToContents() 238 self._pinsTable.headers = ["Name","Net Name","Net Type", deltaSymbol+"Voltage [V]", deltaSymbol+"Current [A]", deltaSymbol+u"Temperature [\u00B0C]"] 239 self._pinsTable.resizeColumnsToContents() 240 vrmHeaders = ["Name", deltaSymbol+"Source\nVoltage [V]", deltaSymbol+"Output\nVoltage [V]", deltaSymbol+"Output\nCurrent [A]", deltaSymbol+"Output\nPower [W]", "Tolerance", deltaSymbol+"Margin\n[mV]"] 241 if self._hasAtLeastOneSenseLine: 242 vrmHeaders += ["Sense\nVoltage [V]", "Sense Port\nVoltage [V]", deltaSymbol+"Sense Diff.\n[mV]"] 243 if self._hasAtLeastOneSwitch: 244 vrmHeaders += ["Input\nVoltage [V]", "USwitch\nCurrent [A]", "LSwitch\nCurrent [A]", "Inductor\nCurrent [A]"] 245 self._vrmsTable.headers = vrmHeaders 246 self._vrmsTable.resizeColumnsToContents() 247 self._viasTable.headers = ["Id", deltaSymbol+"Current [A]", deltaSymbol+u"T [\u00B0C]", deltaSymbol+u"Radius [um]", deltaSymbol+u"Plating [um]", deltaSymbol+u"Area [um**2]"] 248 self._thermalComponentsTable.headers = ["Name", deltaSymbol+"Source [W]", deltaSymbol+"Heat To\nBoard [W]", deltaSymbol+"Heat To\nCase [W]", deltaSymbol+u"T\n[\u00B0C]",deltaSymbol+u"Case \nBottom T[\u00B0C]", deltaSymbol+u"Die T\n[\u00B0C]", deltaSymbol+u"Case \nTop T[\u00B0C]", deltaSymbol+"Thermal Resistance\nBare Board [K/W]"] 249 self._thermalComponentsTable.resizeColumnsToContents() 250 251 for table in [self._vrmsTable, self._sinksTable, self._pinsTable, self._viasTable, self._layersTable, self._thermalComponentsTable]: 252 table.selectionBehavior = TableView.SelectRows 253 table.selectionMode = TableView.ExtendedSelection 254 table.resizeRowsToContents() 255 table.resizeColumnsToContents() 256 table.alternatingRowColors = False 257 table.resizeColumnsToContents() 258 table.onLayoutChanged = lambda y=table: self.onSelectionChanged(y) 259 table.onSelectionChanged = lambda y=table: self.onSelectionChanged(y) 260 table.refresh() 261 262 pinNameToObj = {} 263 for part in empro.activeProject.geometry().flatList(True): 264 if isinstance(part, empro.geometry.OaLayout): 265 for index in range(part._instanceCount()): 266 inst = part._instance(index) 267 for pi in range(inst.instPinCount()): 268 pin = inst.instPin(pi) 269 name = "%s.%s" % (inst.name, pin.name) 270 pinNameToObj[name] = pin 271 self.pinNameToObj = pinNameToObj 272 273 import empro.toolkit.analysis.dc.output 274 empro.toolkit.analysis.dc.output._powerGraphSceneFromResults(self._powerGraphScene, self.results) 275 self._viaUpdate()
276 277 278 @_printexception
279 - def _progressHtmlExport(self, arg1, arg2):
280 import empro 281 msg = { 'temperature' : 'Generating Temperature Plots', 282 'voltage' : 'Generating Voltage Plots', 283 'current' : 'Generating Current Plots', 284 'powerLossDensity' : 'Generating Power Loss Density Plots', 285 }.get(arg1,"Generating Report...") 286 287 prog = { 'temperature' : 0, 288 'voltage' : 1, 289 'current' : 2, 290 'powerLossDensity' : 3, 291 }.get(arg1,0) 292 293 self._progressInitDialog.value = prog 294 self._progressInitDialog.labelText = msg 295 empro.gui.processEvents()
296 297 @_printexception
298 - def _setAlwaysExportToDir(self, path):
299 self.alwaysExport = True 300 self.path = path
301 302 @_printexception
303 - def _exportToHtml(self):
304 import empro 305 import empro.toolkit.analysis.dc.output 306 import os 307 if ( self.alwaysExport ): 308 path = os.path.join(self.path,self.results.resultName) 309 if not os.path.splitext(path)[1]: 310 path += ".html" 311 directory = os.path.split(path)[0] 312 if not (directory == ""): 313 html = empro.toolkit.analysis.dc.output.Html(self.results, self.tableInfo, self._maxCurrent.text, \ 314 self._maxTemperature.text, self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked) 315 html.templatesLocation = os.path.join(os.environ['EMPROHOME'],"empro","toolkit","sipi","dc","data","templates") 316 html.figuresLocation = directory 317 text = html.generate(path) 318 import codecs 319 with codecs.open(path,'w','utf-8') as f: 320 f.write(text) 321 else: 322 defaultPath = os.path.expanduser(".") 323 path = empro.gui.getSaveFileName("Export results_overview to Html", defaultPath, "*.html") 324 if not (path == ""): 325 if not os.path.splitext(path)[1]: 326 path += ".html" 327 directory = os.path.split(path)[0] 328 if not (directory == ""): 329 self._progressInitDialog = empro.gui.ProgressDialog("Generating HTML Report","","bla",0,1) 330 self._progressInitDialog.setCancelButtonText("Hide Progress Window") 331 html = empro.toolkit.analysis.dc.output.Html(self.results, self.tableInfo, self._maxCurrent.text, \ 332 self._maxTemperature.text, self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked) 333 html.templatesLocation = os.path.join(os.environ['EMPROHOME'],"empro","toolkit","sipi","dc","data","templates") 334 html.figuresLocation = directory 335 html.progressCallback = self._progressHtmlExport 336 self._progressInitDialog.minimumDuration = 0 337 self._progressInitDialog.setRange(0,4) 338 text = html.generate(path) 339 import codecs 340 with codecs.open(path,'w','utf-8') as f: 341 f.write(text) 342 self._progressInitDialog.close() 343 _openWebLink(path) 344 import platform 345 if platform.system() == "Windows": 346 path = path.replace('/','\\') 347 empro.gui.MessageBox.information("Export To Html", "File generated %s" % path, empro.gui.Ok, empro.gui.Ok)
348 349 350 @_printexception
351 - def _exportToDocX(self):
352 import empro 353 import empro.toolkit.analysis.dc.output 354 import os 355 if ( self.alwaysExport ): 356 path = os.path.join(self.path,self.results.resultName) 357 if not os.path.splitext(path)[1]: 358 path += ".docx" 359 directory = os.path.split(path)[0] 360 if not (directory == ""): 361 docxinstance = empro.toolkit.analysis.dc.output.Docx(self.results, self.tableInfo,self._maxCurrent.text, \ 362 self._maxTemperature.text,self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked) 363 docxinstance.figuresLocation = directory 364 IOErrorflag = 0 365 try: 366 docxinstance.generate(path) 367 except IOError: 368 empro.gui.MessageBox.information("IOError: File can't be overwritten.", "File with the same name has been opened, it can't be overwritten. \nPlease close it firstly. \nFile is located at %s" % fn, empro.gui.Ok, empro.gui.Ok) 369 IOErrorflag = 1 370 else: 371 defaultPath = os.path.expanduser(".") 372 path = empro.gui.getSaveFileName("Export results_overview to Docx", defaultPath, "*.docx") 373 if not (path == ""): 374 if not os.path.splitext(path)[1]: 375 path += ".docx" 376 directory = os.path.split(path)[0] 377 if not (directory == ""): 378 self._progressInitDialog = empro.gui.ProgressDialog("Generating Docx Report","","bla",0,1) 379 self._progressInitDialog.setCancelButtonText("Hide Progress Window") 380 docxinstance = empro.toolkit.analysis.dc.output.Docx(self.results, self.tableInfo,self._maxCurrent.text, \ 381 self._maxTemperature.text,self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked) 382 docxinstance.figuresLocation = directory 383 docxinstance.progressCallback = self._progressHtmlExport 384 self._progressInitDialog.minimumDuration = 0 385 self._progressInitDialog.setRange(0,4) 386 IOErrorflag = 0 387 try: 388 docxinstance.generate(path) 389 except IOError: 390 empro.gui.MessageBox.information("IOError: File can't be overwritten.", "File with the same name has been opened, it can't be overwritten. \nPlease close it firstly. \nFile is located at %s" % fn, empro.gui.Ok, empro.gui.Ok) 391 IOErrorflag = 1 392 self._progressInitDialog.close() 393 if not (IOErrorflag == 1): 394 _openDocxFile(path) 395 import platform 396 if platform.system() == "Windows": 397 path = path.replace('/','\\') 398 empro.gui.MessageBox.information("Export To Docx", "File generated %s" % path, empro.gui.Ok, empro.gui.Ok)
399 400 @_printexception
401 - def _dummyCallback(self,arg1,arg2):
402 pass
403 404 @_printexception
405 - def _plotOptions(self):
406 import empro.gui 407 import empro 408 widget = empro.gui.Widget() 409 self._optionLayersTable = TableView(widget) 410 self._optionLayersTable.objectName = "Layers" 411 widget.layout = empro.gui.VBoxLayout() 412 widget.layout.addWidget(self._optionLayersTable) 413 self._optionLayersTable.headers = ["Layer","T", "V", "A", "P"] 414 index = 0 415 zSortedLayerNames = [ (k,v['zMax'],v['zMin']) for (k,v) in self.results.layerStatistics.iteritems()] 416 zSortedLayerNames = sorted(zSortedLayerNames, key=lambda x:(-x[2],-x[1])) 417 if self.acceptFlag == 0 : 418 row = [] 419 plot1 = False 420 plot2 = False 421 plot3 = False 422 plot4 = False 423 for layer in zSortedLayerNames: 424 layerName = layer[0] 425 if(index == 0 or index == len(zSortedLayerNames)-1): 426 plot1 = True 427 else: 428 plot1 = False 429 row = [layerName, plot1, plot2, plot3, plot4] 430 self._optionLayersTable.setRow(index, row) 431 index += 1 432 for layerId in [-2,-3]: 433 layerName = {-2 : "top", -3 : "bottom"}[layerId] 434 plot1 = False 435 plot2 = plot3 = plot4 = True 436 row = [layerName, plot1, plot2, plot3, plot4] 437 self._optionLayersTable.setRow(index, row) 438 index += 1 439 else: 440 for row in self.tableInfo: 441 self._optionLayersTable.setRow(index, row) 442 index += 1 443 self._optionLayersTable.setUserCheckableColumns([1,2,3,4]) 444 self._optionLayersTable.columnSizeHints = [(x,20) for x in [200,20,20,20]] 445 self._optionLayersTable.resizeColumnsToContents() 446 self._optionLayersTable.resizeRowsToContents() 447 self._optionsDialog = empro.gui.SimpleDialog(empro.gui.Ok | empro.gui.Cancel) 448 self._optionsDialog.setButtonText(empro.gui.Ok,'Accept') 449 self._optionsDialog.setButtonText(empro.gui.Cancel,'Cancel') 450 self._optionsDialog.title = "DC Results Overview Options" 451 self._optionsDialog.resize(535, 600) 452 self._optionsDialog.layout.add(empro.gui.Label("Select plots to be included in report:\n")) 453 self._optionsDialog.layout.add(self._optionLayersTable) 454 self._optionsDialog.layout.add(empro.gui.Label("Tips:\n\ 455 For html plots, templates are being used.\n\ 456 These are found from a predefined location.\n\ 457 The filepath is <ads_installation>/fem/2017/win32_64/bin/empro/toolkit/sipi/dc/data/templates/\n")) 458 self._optionsDialog.windowFlags = empro.gui.WF_Window 459 self._optionsDialog.windowFlags &= ~empro.gui.WF_WindowStaysOnTopHint 460 self._optionsDialog.onClicked = self.onClicked 461 if self.orgTableInfo == []: 462 for i in range(self._optionLayersTable.rowCount()): 463 self.orgTableInfo.append(self._optionLayersTable.row(i)) 464 self._optionsDialog.show(True) 465 return self.tableInfo
466 467 @_printexception
468 - def onClicked(self,iButtonClicked):
469 if iButtonClicked.text == "Accept": 470 self._accept() 471 if iButtonClicked.text == "Cancel": 472 self._cancel()
473 474 @_printexception
475 - def _cancel(self):
476 if self.tableInfo == []: 477 self.tableInfo = self.orgTableInfo
478 479 @_printexception
480 - def _accept(self):
481 if not self.tableInfo == []: 482 self.tableInfo = [] 483 for i in range(self._optionLayersTable.rowCount()): 484 self.tableInfo.append(self._optionLayersTable.row(i)) 485 self.acceptFlag = 1
486 487 @_printexception
488 - def _compareTo(self,arg):
494 495 @_printexception
496 - def updateInstanceTableVisibility(self, index):
497 curText = self._instanceFilter.currentText() 498 if curText == "All": 499 self._pinsTable.clear() 500 pinData = [(i) for i in self.results.pins] 501 realIndex = 0 502 for pin in pinData: 503 row = [pin.name,pin.netName,pin.netType,pin.voltage,pin.current] 504 self._pinsTable.setRow(realIndex, row) 505 realIndex += 1 506 self._pinsTable.resizeRowsToContents() 507 elif curText == "Top Level Pins": 508 self._pinsTable.clear() 509 pinData = [(i) for i in self.results.pins if not i.name.count(".")] 510 realIndex = 0 511 for pin in pinData: 512 row = [pin.name,pin.netName,pin.netType,pin.voltage,pin.current] 513 self._pinsTable.setRow(realIndex, row) 514 realIndex += 1 515 self._pinsTable.resizeRowsToContents() 516 else: 517 tokens = curText.split("(") 518 targetInstName = tokens[0] 519 targetInstName = targetInstName.strip() 520 self._pinsTable.clear() 521 pinData = [(i) for i in self.results.pins if (i.name.split(".")[0] == targetInstName)] 522 realIndex = 0 523 for pin in pinData: 524 row = [pin.name,pin.netName,pin.netType,pin.voltage,pin.current] 525 self._pinsTable.setRow(realIndex, row) 526 realIndex += 1 527 self._pinsTable.resizeRowsToContents()
528 529 @_printexception
530 - def _viaUpdate(self):
531 maxCurrent = 1e15 532 maxCurrentFormula = self._maxCurrent.text 533 534 showViolatingCurrent = self._showViolatingViasCurrentCheckBox.checked 535 showViolatingT = self._showViolatingViasTCheckBox.checked 536 index = 0 537 self._numberOfViolatingVias = 0 538 self._numberOfViolatingViasT = 0 539 540 import empro 541 lengthUnit = empro.units.unitByAbbreviation("um") 542 areaUnit = empro.units.unitByAbbreviation("squm") 543 celsius = empro.units.unitByAbbreviation("degC") 544 if self._showDifference: 545 celsius = empro.units.unitByAbbreviation("K") 546 547 maxT = 1e15 548 maxTemperatureFormula = self._maxTemperature.text 549 550 self._viasTable.clear() 551 localParamList = empro.activeProject.parameters().clone() 552 localParamList.append("Radius",0.0) 553 localParamList.append("Plating",0.0) 554 localParamList.append("Area",0.0) 555 import math 556 557 for key, via in self.results.viaCurrents.iteritems(): 558 viaCurrent = float(via[0]) 559 viaTemperature = celsius.fromReferenceUnits(self.results.viaMaxTemperatures.get(key,298.15)) 560 radius, plating = self.results.viaRadiusThickness.get(key,(-1,-1)) 561 localParamList.setFormula("Radius",radius) 562 localParamList.setFormula("Plating",plating) 563 area = math.pi*radius*radius 564 if plating>0.0: 565 area -= math.pi*(radius-plating)*(radius-plating) 566 localParamList.setFormula("Area",area) 567 maxCurrent = empro.core.Expression(maxCurrentFormula).evaluate(localParamList) 568 maxT = celsius.fromReferenceUnits(empro.core.Expression(maxTemperatureFormula).evaluate(localParamList)) 569 #print "maxT", maxT, viaTemperature 570 571 currentIsPassed = False 572 if float(via[0]) < maxCurrent: 573 currentIsPassed = True 574 else: 575 self._numberOfViolatingVias += 1 576 577 tempIsPassed = viaTemperature < maxT 578 if not tempIsPassed: 579 self._numberOfViolatingViasT += 1 580 581 hideRow = (showViolatingCurrent and currentIsPassed) or (showViolatingT and tempIsPassed) 582 radiusStr = lengthUnit.fromReferenceUnits(radius) 583 platingStr = lengthUnit.fromReferenceUnits(plating) 584 areaStr = areaUnit.fromReferenceUnits(area) 585 586 if not hideRow: 587 self._viasTable.setRow(index, [str(key), viaCurrent, self._temperatureFormat % viaTemperature, radiusStr, platingStr, areaStr]) 588 self._viasTable.setDecoration(index,1,{True : self._passIcon, False:self._failIcon}[currentIsPassed] ) 589 self._viasTable.setDecoration(index,2,{True : self._passIcon, False:self._failIcon}[tempIsPassed] ) 590 index += 1 591 self._viasTable.resizeRowsToContents() 592 self.refreshTableLayout(self._viasTable) 593 currentViolations = self._numberOfViolatingVias 594 temperatureViolations = self._numberOfViolatingViasT 595 self._currentViolationCount.text = "(%(currentViolations)d Violations)" % vars() 596 self._temperatureViolationCount.text = "(%(temperatureViolations)d Violations)" % vars()
597 598 599 @_printexception
600 - def refreshTableLayout(self, table):
601 w,h = table.size() 602 table.resize((w+1,h)) 603 table.resize((w,h))
604 605 @_printexception
606 - def _layersTab(self):
607 import empro.gui 608 w = empro.gui.Widget() 609 self._layersTable = TableView(w) 610 self._layersTable .objectName = "layers" 611 w.layout = empro.gui.VBoxLayout() 612 w.layout.addWidget(self._layersTable) 613 self._layersTable.headers = [] 614 return w
615 616 @_printexception
617 - def _powerGraphTab(self):
618 import empro.gui 619 w = empro.gui.Widget() 620 w.layout = empro.gui.VBoxLayout() 621 self._powerGraphScene = empro.gui.GraphicsScene() 622 self._powerGraphView = empro.gui.GraphicsView(self._powerGraphScene, w) 623 self._powerGraphView.scale(1,-1) 624 self._powerGraphView.allowDragging = True 625 self._powerGraphView.autoFitScene = False 626 w.layout.addWidget(self._powerGraphView) 627 return w
628 629 @_printexception
630 - def _sinkTab(self):
631 import empro.gui 632 w = empro.gui.Widget() 633 self._sinksTable = TableView(w) 634 self._sinksTable.objectName = "sinks" 635 w.layout = empro.gui.VBoxLayout() 636 w.layout.addWidget(self._sinksTable) 637 self._sinksTable.headers = [] 638 return w
639 640 @_printexception
641 - def _thermalComponentsTab(self):
642 import empro.gui 643 w = empro.gui.Widget() 644 self._thermalComponentsTable = TableView(w) 645 self._thermalComponentsTable.objectName = "thermalComponents" 646 w.layout = empro.gui.VBoxLayout() 647 w.layout.addWidget(self._thermalComponentsTable) 648 self._thermalComponentsTable.headers = [] 649 return w
650 651 @_printexception
652 - def _tabChanged(self,index):
653 pass
654 655 @_printexception
656 - def _evaluateViolations(self):
657 self._viaUpdate() 658 self._evaluateVias.enabled = False
659 660 @_printexception
661 - def _maxCurrentUpdated(self):
662 self._evaluateVias.enabled = True
663 664 665 @_printexception
666 - def _maxTemperatureUpdated(self):
667 self._evaluateVias.enabled = True
668 669 @_printexception
671 self._viaUpdate()
672 673 @_printexception
674 - def _viasTab(self):
675 import empro.gui 676 w = empro.gui.Widget() 677 # create filter widgets 678 self._viasTable = TableView(w) 679 self._maxCurrent = empro.gui.LineEdit("1 + 0*Area A") 680 self._maxCurrent.onUpdate = self._maxCurrentUpdated 681 self.label = Label("Maximum Current:") 682 self._numberOfViolatingVias = 0 683 self._currentViolationCount = Label("(0 Violations)") 684 self._viasTable.objectName = "vias" 685 self._displayViasResultChckBox = empro.gui.CheckBox("Display Results in Layout" ) 686 self._displayViasResultChckBox.checked = True 687 self._displayViasResultChckBox.onToggled = lambda x : self.onCheckBoxClick() 688 self._maxTempLabel = empro.gui.Label("Maximum Temperature") 689 self._maxTemperature = empro.gui.LineEdit("100 degC") 690 self._maxTemperature.onUpdate = self._maxTemperatureUpdated 691 self._temperatureViolationCount = Label("(0 Violations)") 692 self._numberOfViolatingViasT = 0 693 self._showViolatingViasCurrentCheckBox = empro.gui.CheckBox("Only Show Violating Vias (Current)") 694 self._showViolatingViasCurrentCheckBox.onToggled = lambda x : self.onShowViolatingViasOnlyClicked() 695 self._showViolatingViasTCheckBox = empro.gui.CheckBox("Only Show Violating Vias (T)") 696 self._showViolatingViasTCheckBox.onToggled = lambda x : self.onShowViolatingViasOnlyClicked() 697 self._evaluateVias = empro.gui.PushButton("Re-Evaluate") 698 self._evaluateVias.onClicked = lambda x:self._evaluateViolations() 699 self._evaluateVias.enabled = False 700 self._viaUpdate() 701 702 # create filter widget layout 703 filterWidget = empro.gui.Widget() 704 filterWidget.layout = empro.gui.HBoxLayout() 705 filterWidget.layout.contentsMargin = [0, 0, 0, 0] 706 filterWidget.layout.addWidget(self.label) 707 filterWidget.layout.addWidget(self._maxCurrent,1) 708 filterWidget.layout.addWidget(self._currentViolationCount,0,20) 709 filterWidget2 = empro.gui.Widget() 710 filterWidget2.layout = empro.gui.HBoxLayout() 711 filterWidget2.layout.contentsMargin = [0, 0, 0, 0] 712 filterWidget2.layout.addWidget(self._maxTempLabel) 713 filterWidget2.layout.addWidget(self._maxTemperature,1) 714 filterWidget2.layout.addWidget(self._temperatureViolationCount,0,20) 715 filterWidget3 = empro.gui.Widget() 716 filterWidget3.layout = empro.gui.HBoxLayout() 717 filterWidget3.layout.contentsMargin = [0, 0, 0, 0] 718 filterWidget3.layout.addWidget(self._evaluateVias) 719 filterWidget3.layout.addWidget(self._displayViasResultChckBox) 720 filterWidget3.layout.addWidget(self._showViolatingViasCurrentCheckBox) 721 filterWidget3.layout.addWidget(self._showViolatingViasTCheckBox) 722 filterWidget3.layout.addStretch(1) 723 # create main layout 724 w.layout = empro.gui.VBoxLayout() 725 w.layout.addWidget(filterWidget) 726 w.layout.addWidget(filterWidget2) 727 w.layout.addWidget(filterWidget3) 728 w.layout.addWidget(self._viasTable) 729 self._viasTable.headers = [] 730 self._viasTable.resizeColumnsToContents() 731 return w
732 733 @_printexception
734 - def onCheckBoxClick(self):
735 self.onSelectionChanged(self._pinsTable) 736 self.onSelectionChanged(self._viasTable)
737 738 @_printexception
739 - def onSelectionChanged(self, table):
740 # ugly workaround: the table doesn't repaint itself properly when changing the selection. 741 # to work around it, we wiggle the window's size a bit. 742 import empro 743 w, h = table.size() 744 table.resize(w + 2, h) 745 table.resize(w, h) 746 if table.objectName=="pins": 747 selectedPins = [table.data(x,0) for x in table.selectedRows()] 748 points = [] 749 results = [] 750 if self._selectInTreeChckBox.checked: 751 gv = empro.gui.activeProjectView().geometryView() 752 import empro.gui 753 gs = empro.gui.SelectionList.globalSelectionList() 754 gs.clear() 755 gs.insertList([self.pinNameToObj[x] for x in selectedPins]) 756 757 if not self._selectInTreeChckBox.checked: 758 import empro.gui 759 gs = empro.gui.SelectionList.globalSelectionList() 760 gs.clear() 761 762 if self._displayPinsResultChckBox.checked: 763 for pinName in selectedPins: 764 for pin in self.results.pins: 765 if pinName == pin.name: 766 name = pin.name 767 voltage = str(pin.voltage)+" V" 768 current = str(pin.current)+" A" 769 temperature = str(pin.temperature) + " K" 770 pin = self.pinNameToObj[pinName] 771 position = pin.dotPosition 772 data = name+"\n"+voltage+"\n"+current+"\n"+temperature 773 points.append(position) 774 results.append(data) 775 776 gv = empro.gui.activeProjectView().geometryView() 777 key = gv.insertTexts(points,results,self._pinResultHighlightSegment) 778 gv.setRenderingOptions( key, "general displacement = -20") 779 gv.updateView() 780 781 if not self._displayPinsResultChckBox.checked: 782 gv = empro.gui.activeProjectView().geometryView() 783 key = gv.insertTexts([],[],self._pinResultHighlightSegment) 784 gv.updateView() 785 786 if table.objectName=="vias": 787 import empro 788 import time 789 celsius = empro.units.unitByAbbreviation("degC") 790 if self._showDifference: 791 celsius = empro.units.unitByAbbreviation("K") 792 793 ids = [table.data(x,0) for x in table.selectedRows()] 794 cellCoords = [] 795 lineCoords = [] 796 results = [] 797 points = [] 798 799 for id in ids: 800 current, faces = self.results.viaCurrents.get(int(id),0.0) 801 temperature = celsius.fromReferenceUnits(self.results.viaMaxTemperatures.get(int(id),298.15)) 802 cellCoords.extend(faces) 803 results.append(str(current)+" A\n" + (self._temperatureFormat % temperature) + " " + celsius.abbreviation()) 804 points.append(faces[0][0]) 805 for face in faces: 806 lineCoords += [(face[0], face[1]), (face[0], face[2]), (face[2], face[1])] 807 808 gv = empro.gui.activeProjectView() 809 gv = gv.geometryView() 810 key = gv.insertPolygons(cellCoords, self._viaHighlightSegment, self._viaHighlightColor) 811 gv.setRenderingOptions( key, "general displacement = -20") 812 key = gv.insertWeightedLines(lineCoords, self._viaHighlightSegmentLines, 4, self._viaHighlightColor) 813 gv.setRenderingOptions( key, "general displacement = -20") 814 if self._displayViasResultChckBox.checked: 815 key = gv.insertTexts(points,results,self._viaHighlightSegment) 816 gv.setRenderingOptions( key, "general displacement = -20") 817 else: 818 key = gv.insertTexts([],[],self._viaHighlightSegment) 819 gv.updateView()
820 821 @_printexception
822 - def _vrmsTab(self):
823 import empro.gui 824 w = empro.gui.Widget() 825 self._vrmsTable = TableView(w) 826 self._vrmsTable.objectName = "vrms" 827 w.layout = empro.gui.VBoxLayout() 828 w.layout.addWidget(self._vrmsTable) 829 self._vrmsTable.headers = [] 830 return w
831 832 @_printexception
833 - def _pinsTab(self):
834 import empro.gui 835 w = empro.gui.Widget() 836 self._pinsTable = TableView(w) 837 self._pinsTable.objectName = "pins" 838 # create selection filter widgets 839 # -- instance filter widget 840 self._instanceFilterLbl = empro.gui.Label("Select Pins:") 841 self._instanceFilter = empro.gui.ComboBox(w) 842 self._instanceFilter.objectName = "filterCombo" 843 self._instanceFilter.onActivated = self.updateInstanceTableVisibility 844 instanceFilterWidget = empro.gui.Widget() 845 instanceFilterWidget.layout = empro.gui.HBoxLayout() 846 instanceFilterWidget.layout.contentsMargin = [0, 0, 0, 0] 847 instanceFilterWidget.layout.addWidget(self._instanceFilterLbl) 848 instanceFilterWidget.layout.addWidget(self._instanceFilter) 849 instanceFilterWidget.layout.addStretch(1) 850 # -- select in tree filter / display results in layout filter 851 self._selectInTreeChckBox = empro.gui.CheckBox("Select Pins in Project Tree" ) 852 self._selectInTreeChckBox.checked = True 853 self._selectInTreeChckBox.onToggled = lambda x : self.onCheckBoxClick() 854 self._displayPinsResultChckBox = empro.gui.CheckBox("Display Results in Layout" ) 855 self._displayPinsResultChckBox.checked = True 856 self._displayPinsResultChckBox.onToggled = lambda x : self.onCheckBoxClick() 857 pinsDisplayFilterWidget = empro.gui.Widget() 858 pinsDisplayFilterWidget.layout = empro.gui.HBoxLayout() 859 pinsDisplayFilterWidget.layout.contentsMargin = [0, 0, 0, 0] 860 pinsDisplayFilterWidget.layout.addWidget(self._selectInTreeChckBox) 861 pinsDisplayFilterWidget.layout.addWidget(self._displayPinsResultChckBox) 862 pinsDisplayFilterWidget.layout.addStretch(1) 863 # create ins table widgets 864 pinsTableWidget = empro.gui.Widget() 865 pinsTableWidget.layout = empro.gui.HBoxLayout() 866 pinsTableWidget.layout.contentsMargin = [0, 0, 0, 0] 867 pinsTableWidget.layout.addWidget(self._pinsTable) 868 self._pinsTable.headers = [] 869 # create tab layout 870 w.layout = empro.gui.VBoxLayout() 871 w.layout.addWidget(instanceFilterWidget) 872 w.layout.addWidget(pinsDisplayFilterWidget) 873 w.layout.addWidget(pinsTableWidget) 874 return w
875
876 - def show(self):
877 self.dialog.show(False)
878 879 @_printexception
880 - def onFinished(self,result):
881 # clearing the selection 882 import empro 883 gv = empro.gui.activeProjectView() 884 gv = gv.geometryView() 885 key = gv.insertPolygons([], self._viaHighlightSegment, self._viaHighlightColor) 886 key = gv.insertWeightedLines([], self._viaHighlightSegmentLines, 1, self._viaHighlightColor) 887 key = gv.insertTexts([],[],self._pinResultHighlightSegment) 888 key = gv.insertTexts([],[],self._viaHighlightSegment) 889 gv.updateView()
890 891 if False: 892 import empro.toolkit.analysis.dc.results 893 result1 = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-1]) 894 result2 = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-2]) 895 diff = empro.toolkit.analysis.dc.results.DCResultsDiff(result1,result2) 896 resultsDiffView = ResultsOverview(diff) 897 resultsDiffView.show() 898 899 if False: 900 import empro.toolkit.analysis.dc.results 901 result1 = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-2]) 902 resultsDiffView = ResultsOverview(result1) 903 resultsDiffView.show() 904