{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Measure tool\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from itom import dataObject\nfrom itom import ui\nfrom itomUi import ItomUi\nfrom itom import shape\nimport inspect\nimport os.path\nimport numpy as np\n\n\nclass MeasureToolMain(ItomUi):\n\n upDating = True\n measureType = 0\n plotElementType = 0\n\n elementCount = 0\n\n enumGeomNames = [\n \"noType\",\n \"point\",\n \"line\",\n \"rectangle\",\n \"square\",\n \"ellipse\",\n \"circle\",\n \"polygon\",\n ]\n enumGeomIdx = [\n shape.Invalid,\n shape.Point,\n shape.Line,\n shape.Rectangle,\n shape.Square,\n shape.Ellipse,\n shape.Circle,\n shape.Polygon,\n ]\n enumRelationName = None\n enumRelationIdx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n def __init__(self):\n self.upDating = True\n self.measureType = 0\n ownFilename = inspect.getfile(inspect.currentframe())\n ownDir = os.path.dirname(ownFilename)\n uiFile = os.path.join(ownDir, \"uiMeasureToolMain.ui\")\n uiFile = os.path.abspath(uiFile)\n ItomUi.__init__(self, uiFile, ui.TYPEWINDOW, childOfMainWindow=True)\n\n self.gui.measurementTable.call(\"addRelationName\", \"mean value\")\n self.enumRelationName = self.gui.measurementTable[\"relationNames\"]\n self.enumRelationIdx[0] = self.enumRelationName.index(\"N.A.\")\n self.enumRelationIdx[1] = self.enumRelationName.index(\"radius (own)\")\n self.enumRelationIdx[2] = self.enumRelationName.index(\"distance to\")\n self.enumRelationIdx[3] = self.enumRelationName.index(\"length (own)\")\n self.enumRelationIdx[4] = self.enumRelationName.index(\"area\")\n self.enumRelationIdx[5] = self.enumRelationName.index(\"mean value\")\n\n self.elementCount = 0\n\n def show(self, modalLevel=0):\n ret = self.gui.show(modalLevel)\n\n def showObject(self, newObject=None):\n\n if self.measureType != 0:\n self.on_pushButtonCancel_clicked()\n else:\n self.gui.measurementTable.call(\"clearAll\")\n self.gui.dataPlot.call(\"clearGeometricShapes\")\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n\n if newObject is None:\n self.gui.dataPlot[\"source\"] = dataObject.zeros([1, 1])\n else:\n self.gui.dataPlot[\"source\"] = newObject\n\n def clearPlots(self):\n ret = self.gui.dataPlot[\"source\"] = dataObject.zeros([1, 1])\n self.gui.measurementTable.call(\"clearAll\")\n self.gui.dataPlot.call(\"clearGeometricShapes\")\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n\n @ItomUi.autoslot(\"\")\n def on_pushButtonDistanceP2P_clicked(self):\n if self.measureType == 0:\n self.measureType = 2\n self.plotElementTyp = shape.Point\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n self.gui.pushButtonCancel[\"enabled\"] = True\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, True, 2\n )\n\n @ItomUi.autoslot(\"\")\n def on_pushButtonDistanceP2L_clicked(self):\n if self.measureType == 0:\n self.measureType = 3\n self.plotElementTyp = shape.Point\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n self.gui.pushButtonCancel[\"enabled\"] = True\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, True, 1\n )\n\n @ItomUi.autoslot(\"\")\n def on_pushButtonRadius_clicked(self):\n if self.measureType == 0:\n self.measureType = 1\n self.plotElementTyp = shape.Ellipse\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n self.gui.pushButtonCancel[\"enabled\"] = True\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, True, 1\n )\n\n @ItomUi.autoslot(\"\")\n def on_pushButtonMean_clicked(self):\n if self.measureType == 0:\n self.measureType = 4\n self.plotElementTyp = shape.Rectangle\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n self.gui.pushButtonCancel[\"enabled\"] = True\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, True, 1\n )\n\n @ItomUi.autoslot(\"\")\n def on_pushButtonCancel_clicked(self):\n if self.measureType != 0:\n self.measureType = 0\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, False, 0\n )\n self.plotElementTyp = 0\n self.gui.pushButtonCancel[\"enabled\"] = False\n\n @ItomUi.autoslot(\"\")\n def on_pushButtonClearAll_clicked(self):\n if self.measureType != 0:\n self.measureType = 0\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, False, 0\n )\n self.plotElementTyp = 0\n\n self.gui.measurementTable.call(\"clearAll\")\n self.gui.dataPlot.call(\"clearGeometricShapes\")\n self.elementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n\n # @ItomUi.autoslot(\"int\")\n # def on_dataPlot_plotItemChanged(self, index):\n # geometricElements = self.gui.dataPlot[\"geometricElements\"]\n # self.gui.measurementTable[\"source\"] = geometricElements\n @ItomUi.autoslot(\"\")\n def on_dataPlot_geometricShapesDeleted(self):\n self.gui.pushButtonClearAll[\"enabled\"] = False\n\n @ItomUi.autoslot(\"int,ito::Shape\")\n def on_dataPlot_geometricShapeAdded(self, idx, shape):\n self.gui.pushButtonClearAll[\"enabled\"] = True\n\n @ItomUi.autoslot(\"QVector,bool\")\n def on_dataPlot_geometricShapeFinished(self, shapes, aborted):\n geometricShapes = self.gui.dataPlot[\"geometricShapes\"]\n self.gui.measurementTable[\"geometricShapes\"] = geometricShapes\n\n newElementCount = self.gui.dataPlot[\"geometricShapesCount\"]\n\n if self.elementCount + 1 > newElementCount:\n self.measureType = 0\n return\n\n if self.measureType == 1: # radius\n first = geometricShapes[newElementCount - 1]\n self.gui.measurementTable.call(\n \"addRelation\",\n dataObject(\n np.array([first.index, self.enumRelationIdx[1], -1, 0.0])\n ),\n )\n\n elif self.measureType == 2: # distance point to point P2P\n if self.elementCount + 2 <= newElementCount:\n first = geometricShapes[newElementCount - 2]\n second = geometricShapes[newElementCount - 1]\n else:\n first = geometricShapes[newElementCount - 1]\n\n self.gui.measurementTable.call(\n \"addRelation\",\n dataObject(\n np.array(\n [\n first.index,\n self.enumRelationIdx[2],\n second.index,\n 0.0,\n ]\n )\n ),\n )\n\n elif (\n self.measureType == 3\n ): # distance point to point P2L the first time, still missing a line\n self.measureType = 33\n first = geometricShapes[newElementCount - 1]\n self.gui.measurementTable.call(\n \"addRelation\",\n dataObject(\n np.array([first.index, self.enumRelationIdx[2], -1, 0.0])\n ),\n )\n self.plotElementTyp = self.enumGeomIdx[\n self.enumGeomNames.index(\"line\")\n ]\n self.gui.dataPlot.call(\n \"userInteractionStart\", self.plotElementTyp, True, 1\n )\n return\n\n elif (\n self.measureType == 33\n ): # distance point to point P2L the second time, now having a line\n if self.elementCount + 2 <= newElementCount:\n first = geometricShapes[newElementCount - 2]\n second = geometricShapes[newElementCount - 1]\n\n try:\n relToEdit = self.gui.measurementTable[\"lastAddedRelation\"]\n self.gui.measurementTable.call(\n \"modifyRelation\",\n relToEdit,\n dataObject(\n np.array(\n [\n first.index,\n self.enumRelationIdx[2],\n second.index,\n 0.0,\n ]\n )\n ),\n )\n except:\n print(\"setting second geometric element failed\")\n else:\n print(\"setting second geometric element failed\")\n\n elif self.measureType == 4: # mean-Value\n first = geometricShapes[newElementCount - 1]\n try:\n tempObj = self.gui.dataPlot[\"source\"]\n\n rect = geometricShapes[newElementCount - 1]\n x0 = round(\n tempObj.physToPix(min(rect.point1[0], rect.point2[0]), 1)\n )\n x1 = (\n round(\n tempObj.physToPix(\n max(rect.point1[0], rect.point2[0]), 1\n )\n )\n + 1\n )\n x0 = max(x0, 0)\n x1 = max(x1, 0)\n x0 = min(x0, tempObj.shape[tempObj.dims - 1] - 1)\n x1 = min(x1, tempObj.shape[tempObj.dims - 1])\n\n y0 = round(\n tempObj.physToPix(min(rect.point1[1], rect.point2[1]), 1)\n )\n y1 = (\n round(\n tempObj.physToPix(\n max(rect.point1[1], rect.point2[1]), 1\n )\n )\n + 1\n )\n y0 = max(y0, 0)\n y1 = max(y1, 0)\n y0 = min(y0, tempObj.shape[tempObj.dims - 2] - 1)\n y1 = min(y1, tempObj.shape[tempObj.dims - 2])\n\n meanValue = filter(\"meanValue\", tempObj[y0:y1, x0:x1])\n\n except:\n meanValue = np.NaN\n\n self.gui.measurementTable.call(\n \"addRelation\",\n dataObject(\n np.array([first.index, self.enumRelationIdx[4], -1, 0.0])\n ),\n )\n self.gui.measurementTable.call(\n \"addRelation\",\n dataObject(\n np.array(\n [\n first.index,\n self.enumRelationIdx[5] + 0x8000,\n -1,\n meanValue,\n ]\n )\n ),\n )\n\n self.measureType = 0\n self.elementCount = newElementCount\n self.gui.pushButtonCancel[\"enabled\"] = False\n\n\nif __name__ == \"__main__\":\n dObj = dataObject.randN([600, 800], \"float32\")\n measurementTool = MeasureToolMain()\n measurementTool.show()\n dObj.axisScales = (0.2, 0.2)\n dObj.axisUnits = (\"mm\", \"mm\")\n measurementTool.showObject(dObj)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 0 }