def open(self, username="", password=""):
        """Open the MorphoSource page and fill in or capture the url
    """
        if username != "":
            self.setLogin(username, password)

        webWidget = slicer.qSlicerWebWidget()
        slicerGeometry = slicer.util.mainWindow().geometry
        webWidget.size = qt.QSize(slicerGeometry.width(),
                                  slicerGeometry.height())
        webWidget.pos = qt.QPoint(slicerGeometry.x() + 256,
                                  slicerGeometry.y() + 128)
        webWidget.url = "https://www.morphosource.org/LoginReg/form"
        webWidget.show()

        self.webWidget = webWidget
        # TODO: need to expose loadFinished signal from QWebEngine via qSlicerWebWidget
        # so that we will know when to send this (current 2 second delay is a hack
        # that may not always work).
        onFinishLoading = lambda: self.onFinishLoading(username, password)
        connected = self.webWidget.connect('loadFinished(bool)',
                                           onFinishLoading)
        if not connected:
            qt.QTimer.singleShot(
                3000, lambda: self.onFinishLoading(username, password))

        return self.webWidget
 def onSiteButtonClicked(self, site):
   webWidget = slicer.qSlicerWebWidget()
   slicerGeometry = slicer.util.mainWindow().geometry
   webWidget.size = qt.QSize(1536,1024)
   webWidget.pos = qt.QPoint(slicerGeometry.x() + 256, slicerGeometry.y() + 128)
   webWidget.url = site["url"]
   webWidget.show()
   self.webWidgets.append(webWidget)
Exemplo n.º 3
0
 def createWebWidget():
     webWidget = slicer.qSlicerWebWidget()
     slicerGeometry = slicer.util.mainWindow().geometry
     webWidget.size = qt.QSize(slicerGeometry.width(),
                               slicerGeometry.height())
     webWidget.pos = qt.QPoint(slicerGeometry.x() + 256,
                               slicerGeometry.y() + 128)
     webWidget.url = "http://localhost:8000"
     webWidget.show()
     return webWidget
Exemplo n.º 4
0
 def launchCovictory(self, url):
   lm = slicer.app.layoutManager()
   lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalWidescreenView)
   lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalView)
   splitter = lm.threeDWidget(0).parent()
   self.webWidget = slicer.qSlicerWebWidget()
   self.webWidget.url = url
   splitter = lm.threeDWidget(0).parent()
   splitter.insertWidget(0, self.webWidget)
   lm.threeDWidget(0).hide()
   sizes = [int(splitter.height*.67), 0, int(splitter.height*.33)]
   splitter.setSizes(sizes)
Exemplo n.º 5
0
 def onOpenSpecimenPage(self):
     selection = self.resultsTable.selectionModel().selectedRows()
     row = selection[0].row()
     specimen_id = self.result_dataframe.iloc[row].specimen_id
     url = base_specimen_page_url + '/' + specimen_id
     specimen_page = slicer.qSlicerWebWidget()
     geometry = slicer.util.mainWindow().geometry
     geometry.setLeft(geometry.left() + 50)
     geometry.setTop(geometry.top() + 50)
     geometry.setWidth(1080)
     geometry.setHeight(990)
     specimen_page.setGeometry(geometry)
     specimen_page.url = url
     specimen_page.show()
     self.specimen_pages.append(specimen_page)
Exemplo n.º 6
0
    def parallelCoordinatesPureD3(self):
        """Use parallel axes to explore parameter space

    See: http://syntagmatic.github.io/parallel-coordinates/

    Note also experimented with vtk version, but it has fewer features
    and performance is not any better in practice.

    https://vtk.org/Wiki/VTK/Examples/Python/Infovis/ParallelCoordinatesExtraction

    """

        self.volumeStatistics()

        fa = self.arrays['dtd_covariance_FA']
        indices = numpy.where(fa != 0)

        samples = {}
        for key in self.arrays.keys():
            samples[key] = self.arrays[key][indices]

        dataToPlot = []
        for index in range(len(samples['dtd_covariance_FA'])):
            indexData = {}
            for key in self.arrays.keys():
                scalarLabel = key[len('dtd_covariance_'):]
                indexData[scalarLabel] = samples[key][index]
            dataToPlot.append(indexData)

        dataToPlotString = json.dumps(dataToPlot)

        modulePath = os.path.dirname(slicer.modules.multimapper.path)
        resourceFilePath = os.path.join(modulePath, "Resources",
                                        "parallel-template.html")
        html = open(resourceFilePath).read().replace("%%dataToPlot%%",
                                                     dataToPlotString)

        self.webWidget = slicer.qSlicerWebWidget()
        self.webWidget.size = qt.QSize(1024, 512)
        self.webWidget.setHtml(html)
        self.webWidget.show()

        open('/tmp/data.html', 'w').write(html)
Exemplo n.º 7
0
    def test_WebEngine1(self):
        """ Testing WebEngine
    """

        self.delayDisplay("Starting the test")

        webWidget = slicer.qSlicerWebWidget()
        webWidget.size = qt.QSize(1024, 512)
        webWidget.webView().url = qt.QUrl("")
        webWidget.show()
        self.delayDisplay('Showing widget')

        webWidget.evalJS("""
        const paragraph = document.createElement('p');
        paragraph.innerText = 'Hello from Slicer!';
        document.body.appendChild(paragraph);
    """)
        self.delayDisplay('Slicer should be saying hello!')

        #
        # Test javascript evaluation + use of "evalResult()" signal
        #
        webWidget.connect("evalResult(QString,QString)", self.onEvalResult)

        self.delayDisplay('Slicer setting a javascript value')

        webWidget.evalJS("const valueFromSlicer = 42;")
        webWidget.evalJS("valueFromSlicer;")

        iteration = 0
        while not self.gotResponse and iteration < 3:
            # Specify an explicit delay to ensure async execution by the
            # webengine has completed.
            self.delayDisplay('Waiting for response...', msec=500)
            iteration += 1
        webWidget.disconnect("evalResult(QString,QString)", self.onEvalResult)

        if not self.gotResponse:
            raise RuntimeError("Never got response from evalJS")

        if not self.gotCorrectResponse:
            raise AssertionError("Did not get back expected result!")

        #
        # Test python evaluation from javascript
        #
        self.delayDisplay('Call a python method')

        slicer.app.settings().setValue("WebEngine/AllowPythonExecution",
                                       ctk.ctkMessageBox.AcceptRole)

        webWidget.evalJS(r"""
        let pythonCode = "dialog = qt.QInputDialog(slicer.util.mainWindow())\n";
        pythonCode += "dialog.setLabelText('hello')\n";
        pythonCode += "dialog.open()\n";
        pythonCode += "qt.QTimer.singleShot(1000, dialog.close)\n";

        window.slicerPython.evalPython(pythonCode);
    """)

        self.delayDisplay('Test access to python via js', msec=500)

        if hasattr(slicer.modules, 'slicerPythonValueFromJS'):
            del slicer.modules.slicerPythonValueFromJS

        webWidget.evalJS("""
        window.slicerPython.evalPython("slicer.modules.slicerPythonValueFromJS = 42");
    """)

        iteration = 0
        while iteration < 3 and not hasattr(slicer.modules,
                                            'slicerPythonValueFromJS'):
            # Specify an explicit delay to ensure async execution by the
            # webengine has completed.
            self.delayDisplay('Waiting for python value from JS...', msec=500)
            iteration += 1

        if iteration >= 3:
            raise RuntimeError("Couldn't get python value back from JS")

        self.delayDisplay('Value of %d received via javascipt' %
                          slicer.modules.slicerPythonValueFromJS)

        del slicer.modules.slicerPythonValueFromJS

        self.delayDisplay('Test passed!')
Exemplo n.º 8
0
  def test_WebEngine1(self):
    """ Testing WebEngine
    """

    self.delayDisplay("Starting the test")


    webWidget = slicer.qSlicerWebWidget()
    webWidget.size = qt.QSize(1024,512)
    webWidget.webView().url = qt.QUrl("")
    webWidget.show()
    self.delayDisplay('Showing widget')

    webWidget.evalJS("""
        const paragraph = document.createElement('p');
        paragraph.innerText = 'Hello from Slicer!';
        document.body.appendChild(paragraph);
    """)
    self.delayDisplay('Slicer should be saying hello!')

    #
    # Test javascript evaluation + use of "evalResult()" signal
    #
    webWidget.connect("evalResult(QString,QString)", self.onEvalResult)

    self.delayDisplay('Slicer setting a javascript value')

    webWidget.evalJS("const valueFromSlicer = 42;")
    webWidget.evalJS("valueFromSlicer;");

    iteration = 0
    while not self.gotResponse and iteration < 3:
      # Specify an explicit delay to ensure async execution by the
      # webengine has completed.
      self.delayDisplay('Waiting for response...', msec=500)
      iteration += 1
    webWidget.disconnect("evalResult(QString,QString)", self.onEvalResult)

    if not self.gotResponse:
      raise RuntimeError("Never got response from evalJS")

    if not self.gotCorrectResponse:
      raise AssertionError("Did not get back expected result!")

    #
    # Test python evaluation from javascript
    #
    self.delayDisplay('Call a python method')

    slicer.app.settings().setValue("WebEngine/AllowPythonExecution", ctk.ctkMessageBox.AcceptRole)

    webWidget.evalJS(r"""
        let pythonCode = "dialog = qt.QInputDialog(slicer.util.mainWindow())\n";
        pythonCode += "dialog.setLabelText('hello')\n";
        pythonCode += "dialog.open()\n";
        pythonCode += "qt.QTimer.singleShot(1000, dialog.close)\n";

        window.slicerPython.evalPython(pythonCode);
    """)

    self.delayDisplay('Test access to python via js', msec=500)

    if hasattr(slicer.modules, 'slicerPythonValueFromJS'):
      del slicer.modules.slicerPythonValueFromJS

    webWidget.evalJS("""
        window.slicerPython.evalPython("slicer.modules.slicerPythonValueFromJS = 42");
    """)

    iteration = 0
    while iteration < 3 and not hasattr(slicer.modules, 'slicerPythonValueFromJS'):
      # Specify an explicit delay to ensure async execution by the
      # webengine has completed.
      self.delayDisplay('Waiting for python value from JS...', msec=500)
      iteration += 1

    if iteration >= 3:
      raise RuntimeError("Couldn't get python value back from JS")

    self.delayDisplay('Value of %d received via javascipt' % slicer.modules.slicerPythonValueFromJS)

    del slicer.modules.slicerPythonValueFromJS

    self.delayDisplay('Test passed!')
Exemplo n.º 9
0
    def parallelCoordinatesParCoords_RandomSample(self, sampleSize=1000):
        """Use parallel axes to explore parameter space

    See: http://syntagmatic.github.io/parallel-coordinates/
    https://github.com/BigFatDog/parcoords-es

    Note also experimented with vtk version, but it has fewer features
    and performance is not any better in practice.

    https://vtk.org/Wiki/VTK/Examples/Python/Infovis/ParallelCoordinatesExtraction

    """

        self.volumeStatistics()

        fa = self.arrays['dtd_covariance_FA']
        indices = numpy.where(fa != 0)

        ijkCoordinates = numpy.transpose(indices)
        ijkToRAS = vtk.vtkMatrix4x4()
        slicer.util.getNode('dtd_covariance_FA').GetIJKToRASMatrix(ijkToRAS)
        rasCoordinates = []

        samples = {}
        for key in self.arrays.keys():
            samples[key] = self.arrays[key][indices]

        dataToPlot = []
        randomSample = random.sample(range(len(samples['dtd_covariance_FA'])),
                                     sampleSize)
        sampleIndex = 0
        for index in randomSample:
            indexData = {}
            for key in self.arrays.keys():
                scalarLabel = key[len('dtd_covariance_'):]
                indexData[scalarLabel] = samples[key][index]
            dataToPlot.append(indexData)
            ijk = [*numpy.flip(numpy.transpose(indices)[index]), 1]
            rasCoordinates.append(ijkToRAS.MultiplyPoint(ijk))
            sampleIndex += 1

        dataToPlotString = json.dumps(dataToPlot)
        rasCoordinatesString = json.dumps(rasCoordinates)

        modulePath = os.path.dirname(slicer.modules.multimapper.path)
        resourceFilePath = os.path.join(modulePath, "Resources",
                                        "ParCoords-template.html")
        html = open(resourceFilePath).read()
        html = html.replace("%%dataToPlot%%", dataToPlotString)
        html = html.replace("%%rasCoordinates%%", rasCoordinatesString)

        self.webWidget = slicer.qSlicerWebWidget()
        self.webWidget.size = qt.QSize(1024, 768)
        self.webWidget.setHtml(html)
        self.webWidget.show()

        def crosshairCallback(observer, eventID):
            crosshairNode = slicer.mrmlScene.GetFirstNodeByClass(
                'vtkMRMLCrosshairNode')
            ras = [
                0,
            ] * 3
            crosshairNode.GetCursorPositionRAS(ras)
            print(ras)
            # TODO: update selector ranges based on QTI statistics

        crosshairNode = slicer.mrmlScene.GetFirstNodeByClass(
            'vtkMRMLCrosshairNode')
        event = vtk.vtkCommand.ModifiedEvent
        id_ = crosshairNode.AddObserver(event, crosshairCallback)
        self.observerObjectIDPairs.append((crosshairNode, id_))

        # save for debugging
        open('/tmp/data.html', 'w').write(html)
Exemplo n.º 10
0
    def parallelCoordinatesSegmentation(self,
                                        segmentationNode=None,
                                        labelmapNode=None):
        """
    Like parallelCoordinatesParCoords_RandomSample below, but
    parcoords plot created from segmentation
    """

        self.volumeStatistics()

        if not segmentationNode:
            try:
                segmentationNode = slicer.util.getNode('Segmentation')
            except slicer.util.MRMLNodeNotFoundException:
                pass
        if not segmentationNode:
            print("need a segmentation")
            slicer.util.selectModule("SegmentEditor")
            return
        if not labelmapNode:
            try:
                labelmapNode = slicer.util.getNode('Segmentation-labelmap')
            except slicer.util.MRMLNodeNotFoundException:
                labelmapNode = slicer.mrmlScene.AddNewNodeByClass(
                    'vtkMRMLLabelMapVolumeNode')
                labelmapNode.SetName("Segmentation-labelmap")
        segmentIDs = vtk.vtkStringArray()
        segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)
        slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode(
            segmentationNode, segmentIDs, labelmapNode,
            self.nodes['dtd_covariance_FA'])
        labelArray = slicer.util.arrayFromVolume(labelmapNode)

        # list of non-zero segments in the labelmap
        segmentIndices = list(numpy.unique(labelArray))[1:]

        # data colors to match the segmentation colors to pass to js
        segmentation = segmentationNode.GetSegmentation()
        dataColors = [[0, 0, 0]]
        for colorNumber in range(len(segmentIndices)):
            dataColor = segmentation.GetNthSegment(colorNumber).GetColor()
            dataColors.append(dataColor)

        # make individual sample lines for parallel coordinates
        ijkToRAS = vtk.vtkMatrix4x4()
        labelmapNode.GetIJKToRASMatrix(ijkToRAS)
        rasCoordinates = []
        dataToPlot = []
        for segmentIndex in segmentIndices:
            # one data sample from each array per labeled voxel
            coordinates = numpy.transpose(
                numpy.where(labelArray == segmentIndex))
            self._coordinates = coordinates
            samples = {}
            for key in self.arrays.keys():
                samples[key] = []
                for coordinate in coordinates:
                    self._array = self.arrays[key]
                    samples[key].append(self.arrays[key][coordinate[0]][
                        coordinate[1]][coordinate[2]])
            for coordinateNumber in range(len(coordinates)):
                indexData = {}
                indexData['segmentIndex'] = int(segmentIndex)
                for key in self.arrays.keys():
                    scalarLabel = key[len('dtd_covariance_'):]
                    indexData[scalarLabel] = samples[key][coordinateNumber]
                dataToPlot.append(indexData)
                ijkw = [*numpy.flip(coordinates)[coordinateNumber], 1]
                ijkw = [*numpy.flip(coordinates)[coordinateNumber], 1]
                rasCoordinate = ijkToRAS.MultiplyPoint(ijkw)
                rasCoordinates.append(rasCoordinate)

        dataColorsString = json.dumps(dataColors)
        dataToPlotString = json.dumps(dataToPlot)
        rasCoordinatesString = json.dumps(rasCoordinates)

        modulePath = os.path.dirname(slicer.modules.multimapper.path)
        resourceFilePath = os.path.join(modulePath, "Resources",
                                        "ParCoords-SEG-template.html")
        html = open(resourceFilePath).read()
        html = html.replace("%%dataColors%%", dataColorsString)
        html = html.replace("%%dataToPlot%%", dataToPlotString)
        html = html.replace("%%rasCoordinates%%", rasCoordinatesString)

        self.webWidget = slicer.qSlicerWebWidget()
        self.webWidget.size = qt.QSize(1024, 768)
        self.webWidget.setHtml(html)
        self.webWidget.show()

        def crosshairCallback(observer, eventID):
            crosshairNode = slicer.mrmlScene.GetFirstNodeByClass(
                'vtkMRMLCrosshairNode')
            ras = [
                0,
            ] * 3
            crosshairNode.GetCursorPositionRAS(ras)
            print(ras)
            # TODO: update selector ranges based on QTI statistics

        crosshairNode = slicer.mrmlScene.GetFirstNodeByClass(
            'vtkMRMLCrosshairNode')
        event = vtk.vtkCommand.ModifiedEvent
        id_ = crosshairNode.AddObserver(event, crosshairCallback)
        self.observerObjectIDPairs.append((crosshairNode, id_))

        # save for debugging
        open('/tmp/data.html', 'w').write(html)
Exemplo n.º 11
0
 def openQtLocalConnection(self):
     self.webWidget = slicer.qSlicerWebWidget()
     self.webWidget.url = f'http://localhost:{self.logic.port}'
     self.webWidget.show()