Пример #1
0
  def setupMeasurementsArea(self):
    self.measurementsGroupBox = qt.QGroupBox("Measurements")
    self.measurementsGroupBox.setLayout(qt.QGridLayout())
    self.tableView = slicer.qMRMLTableView()
    self.tableView.setMinimumHeight(150)
    self.tableView.setMaximumHeight(150)
    self.tableView.setSelectionBehavior(qt.QTableView.SelectRows)

    if ModuleWidgetMixin.isQtVersionOlder():
      self.tableView.horizontalHeader().setResizeMode(qt.QHeaderView.Stretch)
    else:
      self.tableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch)

    self.fourUpTableView = None
    self.segmentStatisticsConfigButton = self.createButton("Segment Statistics Parameters")

    self.calculateMeasurementsButton = self.createButton("Calculate Measurements", enabled=False)
    self.calculateAutomaticallyCheckbox = qt.QCheckBox("Auto Update")
    self.calculateAutomaticallyCheckbox.checked = True

    self.measurementsGroupBox.layout().addWidget(self.tableView, 0, 0, 1, 2)
    self.measurementsGroupBox.layout().addWidget(self.segmentStatisticsConfigButton, 1, 0, 1, 2)
    self.measurementsGroupBox.layout().addWidget(self.calculateMeasurementsButton, 2, 0)
    self.measurementsGroupBox.layout().addWidget(self.calculateAutomaticallyCheckbox, 2, 1)

    self.mainModuleWidgetLayout.addWidget(self.measurementsGroupBox)
Пример #2
0
  def setupMeasurementsArea(self):
    self.measurementsGroupBox = qt.QGroupBox("Measurements")
    self.measurementsGroupBox.setLayout(qt.QGridLayout())
    self.tableView = slicer.qMRMLTableView()
    self.tableView.setMinimumHeight(150)
    self.tableView.setMaximumHeight(150)
    self.tableView.setSelectionBehavior(qt.QTableView.SelectRows)

    if ModuleWidgetMixin.isQtVersionOlder():
      self.tableView.horizontalHeader().setResizeMode(qt.QHeaderView.Stretch)
    else:
      self.tableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch)

    self.fourUpTableView = None
    self.segmentStatisticsConfigButton = self.createButton("Segment Statistics Parameters")

    self.calculateMeasurementsButton = self.createButton("Calculate Measurements", enabled=False)
    self.calculateAutomaticallyCheckbox = qt.QCheckBox("Auto Update")
    self.calculateAutomaticallyCheckbox.checked = True

    self.measurementsGroupBox.layout().addWidget(self.tableView, 0, 0, 1, 2)
    self.measurementsGroupBox.layout().addWidget(self.segmentStatisticsConfigButton, 1, 0, 1, 2)
    self.measurementsGroupBox.layout().addWidget(self.calculateMeasurementsButton, 2, 0)
    self.measurementsGroupBox.layout().addWidget(self.calculateAutomaticallyCheckbox, 2, 1)

    self.mainModuleWidgetLayout.addWidget(self.measurementsGroupBox)
Пример #3
0
 def setFOV2Largest2DRegion(self, widget, largestLabel=None, factor=1.5):
   if not largestLabel:
     largestLabel = self.findLargest2DRegion(self.segmentationNode)
   slicer.mrmlScene.AddNode(largestLabel)
   sliceLogic = widget.sliceLogic()
   sliceNode = sliceLogic.GetSliceNode()
   compositeNode = widget.mrmlSliceCompositeNode()
   savedVolumeID = compositeNode.GetBackgroundVolumeID()
   savedFOV = sliceNode.GetFieldOfView()
   compositeNode.SetBackgroundVolumeID(largestLabel.GetID())
   sliceLogic.FitSliceToAll()
   compositeNode.SetBackgroundVolumeID(savedVolumeID)
   FOV = sliceNode.GetFieldOfView()
   ModuleWidgetMixin.setFOV(sliceLogic, [FOV[0] * factor, FOV[1] * factor, FOV[2]])
   slicer.mrmlScene.RemoveNode(largestLabel)
   return largestLabel
    def getData(self):
        data = ""

        prostateMap = ProstateSectorMapDialog()
        prostateMap.displayCheckboxBorder(visible=False)

        for finding in self._assessmentCategory.getFindings():
            prostateMap.resetButtons()
            prostateMap.setSelectedSectors(finding.getSectors())
            prostateMap.setButtonsVisible(checkedOnly=True)

            data += '''
        <div class="print-friendly">
          <h2>{0}</h2>
          <table border=1 width='100%' cellPadding=3 cellSpacing=0>
            {1}
          </table>
          <br>
        </div>
        '''.format(
                finding.getName(), "".join([
                    self.sectorMapScreenShot.format(
                        ModuleWidgetMixin.pixelmapAsRaw(pixmap))
                    for pixmap in prostateMap.getScreenShots()
                ]))

        return data
Пример #5
0
 def setFOV2Largest2DRegion(self, widget, largestLabel=None, factor=1.5):
   if not largestLabel:
     largestLabel = self.findLargest2DRegion(self.segmentationNode)
   slicer.mrmlScene.AddNode(largestLabel)
   sliceLogic = widget.sliceLogic()
   sliceNode = sliceLogic.GetSliceNode()
   compositeNode = widget.mrmlSliceCompositeNode()
   savedVolumeID = compositeNode.GetBackgroundVolumeID()
   savedFOV = sliceNode.GetFieldOfView()
   compositeNode.SetBackgroundVolumeID(largestLabel.GetID())
   sliceLogic.FitSliceToAll()
   compositeNode.SetBackgroundVolumeID(savedVolumeID)
   FOV = sliceNode.GetFieldOfView()
   ModuleWidgetMixin.setFOV(sliceLogic, [FOV[0] * factor, FOV[1] * factor, FOV[2]])
   slicer.mrmlScene.RemoveNode(largestLabel)
   return largestLabel
Пример #6
0
  def viewerPerVolume(cls, volumeNodes, layout, background, opacity=1.0):
    """ Load each volume in the scene into its own slice viewer and link them all together.
    If background is specified, put it in the background of all viewers and make the other volumes be the foreground.
    If label is specified, make it active as the label layer of all viewers. Return a map of slice nodes indexed by
    the view name (given or generated). Opacity applies only when background is selected.
    """

    if not volumeNodes:
      raise ValueError("VolumeNodes are supposed to be non empty")

    layoutManager = slicer.app.layoutManager()
    layoutManager.setLayout(layout)

    sliceWidgets = list(ModuleWidgetMixin.getAllVisibleWidgets())

    slicer.app.processEvents()

    for index, volume in enumerate(volumeNodes):
      sliceWidget = sliceWidgets[index]
      volumeNodeID = volume.GetID()

      compositeNode = sliceWidget.mrmlSliceCompositeNode()
      compositeNode.SetBackgroundVolumeID(background.GetID())
      compositeNode.SetForegroundVolumeID(volumeNodeID)
      compositeNode.SetForegroundOpacity(opacity)

      sliceNode = sliceWidget.mrmlSliceNode()
      orientation = cls.getOrientation(volume)
      if orientation:
        sliceNode.SetOrientation(orientation)
      sliceNode.RotateToVolumePlane(volume)
      sliceWidget.fitSliceToBackground()
Пример #7
0
 def addSideBySideSliceAnnotations(self):
   self.removeSliceAnnotations()
   kwargs = {"yPos":55 if ModuleWidgetMixin.isQtVersionOlder() else 80, "size":30}
   self.sliceAnnotations.append(SliceAnnotation(self.redWidget, constants.LEFT_VIEWER_SLICE_ANNOTATION_TEXT, **kwargs))
   self.sliceAnnotations.append(SliceAnnotation(self.yellowWidget, constants.RIGHT_VIEWER_SLICE_ANNOTATION_TEXT, **kwargs))
   self.addNewImageAnnotation(self.yellowWidget, constants.RIGHT_VIEWER_SLICE_NEEDLE_IMAGE_ANNOTATION_TEXT)
   self.addOldImageAnnotation(self.yellowWidget, constants.RIGHT_VIEWER_SLICE_TRANSFORMED_ANNOTATION_TEXT)
   self.addRegistrationResultStatusAnnotation(self.yellowWidget)
Пример #8
0
 def setTargetTableSizeConstraints(self):
   method = getattr(self.targetTable.horizontalHeader(),
                    "setResizeMode" if ModuleWidgetMixin.isQtVersionOlder() else
                    "setSectionResizeMode")
   method(qt.QHeaderView.Stretch)
   method(0, qt.QHeaderView.Stretch)
   method(1, qt.QHeaderView.ResizeToContents)
   method(2, qt.QHeaderView.ResizeToContents)
Пример #9
0
 def addFourUpSliceAnnotations(self):
   self.removeSliceAnnotations()
   if not (self.currentResult.skipped or (self.session.seriesTypeManager.isCoverProstate(self.currentResult.name) and
                                            not self.session.data.usePreopData)):
     self.sliceAnnotations.append(SliceAnnotation(self.redWidget, constants.RIGHT_VIEWER_SLICE_ANNOTATION_TEXT,
                                                  yPos=50 if ModuleWidgetMixin.isQtVersionOlder() else 75, size=20))
     self.addNewImageAnnotation(self.redWidget, constants.RIGHT_VIEWER_SLICE_NEEDLE_IMAGE_ANNOTATION_TEXT, size=15)
     self.addOldImageAnnotation(self.redWidget, constants.RIGHT_VIEWER_SLICE_TRANSFORMED_ANNOTATION_TEXT, size=15)
   self.addRegistrationResultStatusAnnotation(self.redWidget)
Пример #10
0
 def _fitIntoViewport(self, size):
     tempSize = self.textProperty.GetFontSize()
     self.textProperty.SetFontSize(size)
     self.textActor.SetTextProperty(self.textProperty)
     if self._getFontWidth() > (self.sliceView.width if ModuleWidgetMixin.isQtVersionOlder() else \
             self.sliceView.width * self.sliceView.devicePixelRatio()):
         self.textProperty.SetFontSize(tempSize)
         self.textActor.SetTextProperty(self.textProperty)
         return False
     return True
Пример #11
0
 def onInvokeRegistration(self, initial=True, retryMode=False, segmentationData=None):
   self.progress = ModuleWidgetMixin.createProgressDialog(maximum=4, value=1, windowFlags=qt.Qt.CustomizeWindowHint |
                                                                                          qt.Qt.WindowTitleHint)
   self.progress.setCancelButton(None)
   if initial:
     self.applyInitialRegistration(retryMode, segmentationData, progressCallback=self.updateProgressBar)
   else:
     self.applyRegistration(progressCallback=self.updateProgressBar)
   self.progress.close()
   self.progress = None
   logging.debug('Re-Registration is done')
    def setupViewSettingsArea(self):
        self.fourUpSliceLayoutButton = FourUpLayoutButton()
        self.fourUpSliceTableViewLayoutButton = FourUpTableViewLayoutButton()
        self.crosshairButton = CrosshairButton()
        self.crosshairButton.setSliceIntersectionEnabled(True)

        hbox = ModuleWidgetMixin.createHLayout([
            self.fourUpSliceLayoutButton,
            self.fourUpSliceTableViewLayoutButton, self.crosshairButton
        ])
        self.layout.addWidget(hbox)
Пример #13
0
 def targetList(self, targetList):
   self._targetList = targetList
   if self.currentGuidanceComputation and self.observer:
     self.self.currentGuidanceComputation.RemoveObserver(self.observer)
   self.currentGuidanceComputation = self.getOrCreateNewGuidanceComputation(targetList)
   if self.currentGuidanceComputation:
     self.observer = self.currentGuidanceComputation.addEventObserver(vtk.vtkCommand.ModifiedEvent,
                                                                      self.updateHoleAndDepth)
   if ModuleWidgetMixin.isQtVersionOlder():
     self.reset()
   else:
     self.beginResetModel()
     self.endResetModel()
Пример #14
0
 def _applyVerticalAlign(self):
     sliceViewHeight = self.sliceView.height if ModuleWidgetMixin.isQtVersionOlder() else \
       self.sliceView.height * self.sliceView.devicePixelRatio()
     centerY = int((sliceViewHeight - self._getFontHeight()) / 2)
     if self.yPos:
         yPos = self.yPos if 0 < self.yPos < centerY else centerY
     else:
         if self.verticalAlign == self.ALIGN_TOP:
             yPos = sliceViewHeight - self._getFontHeight()
         elif self.verticalAlign == self.ALIGN_CENTER:
             yPos = centerY
         elif self.verticalAlign == self.ALIGN_BOTTOM:
             yPos = 0
     return int(yPos)
Пример #15
0
 def _applyHorizontalAlign(self):
     sliceViewWidth = self.sliceView.width if ModuleWidgetMixin.isQtVersionOlder() else \
       self.sliceView.width * self.sliceView.devicePixelRatio()
     centerX = int((sliceViewWidth - self._getFontWidth()) / 2)
     if self.xPos:
         xPos = self.xPos if 0 < self.xPos < centerX else centerX
     else:
         if self.horizontalAlign == self.ALIGN_LEFT:
             xPos = 0
         elif self.horizontalAlign == self.ALIGN_CENTER:
             xPos = centerX
         elif self.horizontalAlign == self.ALIGN_RIGHT:
             xPos = sliceViewWidth - self._getFontWidth()
     return int(xPos)
Пример #16
0
 def _onAnnotationButtonClicked(self, button, checked):
     currentItem = self._annotationListWidget.currentItem()
     if not currentItem:
         return
     itemWidget = self._annotationListWidget.itemWidget(currentItem)
     seriesType = itemWidget.getSeriesType()
     if checked:
         for b in self._annotationButtonGroup.buttons():
             if b.checked and b is not button:
                 b.checked = False
         for w in ModuleWidgetMixin.getAllVisibleWidgets():
             enabled = w.mrmlSliceCompositeNode().GetForegroundVolumeID() is not None and seriesType.getVolume() is \
                       slicer.mrmlScene.GetNodeByID(w.mrmlSliceCompositeNode().GetForegroundVolumeID())
             w.enabled = enabled
             w.setStyleSheet("#frame{{border: 5px ridge {};}}".format(
                 "green" if enabled else "black"))
         self._onAnnotationToolSelected(seriesType,
                                        button.property("MRML_NODE_CLASS"))
     else:
         for w in ModuleWidgetMixin.getAllVisibleWidgets():
             w.enabled = True
             w.setStyleSheet("")
         self._onAnnotationToolDeselected(
             seriesType, button.property("MRML_NODE_CLASS"))
Пример #17
0
  def _onLoadButtonClicked(self):
    self._dataSelectionDialog = DataSelectionDialog()
    self._loadedVolumeNodes = OrderedDict()

    nodeAddedObserver = slicer.mrmlScene.AddObserver(slicer.mrmlScene.NodeAddedEvent, self._onVolumeNodeAdded)
    nodeRemovedObserver = slicer.mrmlScene.AddObserver(slicer.mrmlScene.NodeRemovedEvent, self._onVolumeNodeRemoved)
    try:
      if self._dataSelectionDialog.exec_():
        self._hangingProtocol = HangingProtocolFactory.getHangingProtocol(self.loadedVolumeNodes.values())
        if not self._hangingProtocol:
          raise RuntimeError("No eligible hanging protocol found.")
        background = list(self._loadedVolumeNodes.values())[0]
        self.logic.viewerPerVolume(volumeNodes=self._loadedVolumeNodes.values(), layout=self._hangingProtocol.LAYOUT,
                                   background=background)
        ModuleWidgetMixin.linkAllSliceWidgets(1)
        for sliceWidget in ModuleWidgetMixin.getAllVisibleWidgets():
          sliceWidget.mrmlSliceNode().RotateToVolumePlane(background)
        self._checkForMultiVolumes()
    except Exception as exc:
      logging.error(exc)
    finally:
      slicer.mrmlScene.RemoveObserver(nodeAddedObserver)
      slicer.mrmlScene.RemoveObserver(nodeRemovedObserver)
      self.updateGUIFromData()
Пример #18
0
 def addNewImageAnnotation(self, widget, text, size=20):
   self.newImageAnnotation = SliceAnnotation(widget, text, yPos=35 if ModuleWidgetMixin.isQtVersionOlder() else 45,
                                             opacity=0.0, color=(0, 0.5, 0), size=size)
   self.sliceAnnotations.append(self.newImageAnnotation)
Пример #19
0
 def updateProgressBar(self, **kwargs):
     ModuleWidgetMixin.updateProgressBar(self,
                                         progress=self.progress,
                                         **kwargs)
Пример #20
0
class SliceTrackerConstants(object):

  MODULE_NAME = "SliceTracker"

  PREOP_SAMPLE_DATA_URL = 'https://github.com/SlicerProstate/SliceTracker/releases/download/test-data/Preop-deid.zip'
  INTRAOP_SAMPLE_DATA_URL = 'https://github.com/SlicerProstate/SliceTracker/releases/download/test-data/Intraop-deid.zip'

  JSON_FILENAME = "results.json"

  MISSING_PREOP_ANNOTATION_TEXT = "No preop data available"
  LEFT_VIEWER_SLICE_ANNOTATION_TEXT = 'BIOPSY PLAN'
  RIGHT_VIEWER_SLICE_ANNOTATION_TEXT = 'TRACKED TARGETS'
  RIGHT_VIEWER_SLICE_TRANSFORMED_ANNOTATION_TEXT = 'OLD'
  RIGHT_VIEWER_SLICE_NEEDLE_IMAGE_ANNOTATION_TEXT = 'NEW'
  APPROVED_RESULT_TEXT_ANNOTATION = "approved"
  REJECTED_RESULT_TEXT_ANNOTATION = "rejected"
  SKIPPED_RESULT_TEXT_ANNOTATION = "skipped"

  LAYOUT_RED_SLICE_ONLY = slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView
  LAYOUT_FOUR_UP = slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView
  LAYOUT_FOUR_UP_QUANTITATIVE = slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpPlotView
  LAYOUT_SIDE_BY_SIDE = slicer.vtkMRMLLayoutNode.SlicerLayoutSideBySideView
  ALLOWED_LAYOUTS = [LAYOUT_SIDE_BY_SIDE, LAYOUT_FOUR_UP, LAYOUT_RED_SLICE_ONLY, LAYOUT_FOUR_UP_QUANTITATIVE]

  PLANNING_IMAGE = "PLANNING IMAGE"
  COVER_PROSTATE = "COVER PROSTATE"
  COVER_TEMPLATE = "COVER TEMPLATE"
  GUIDANCE_IMAGE = "GUIDANCE"
  VIBE_IMAGE = "VIBE"
  OTHER_IMAGE = "OTHER"

  TRACKABLE_IMAGE_TYPES = [COVER_PROSTATE, COVER_TEMPLATE, GUIDANCE_IMAGE]

  ZFrame_INSTRUCTION_STEPS = {1: "Scroll and click into ZFrame center to set ROI center",
                              2: "Click outside of upper right ZFrame corner to set ROI border"}

  IntraopSeriesSelectorToolTip = """
  <html>
    <head>
      <style type="text/css"> </style>
    </head>
    <body style="font-family:'Lucida Grande',sans-serif; font-size: 12pt; font-weight: 400; font-style: normal;border: 1px solid black;margin-top:0px;">
      <table cellspacing=5>
        <tbody>
          <tr>
            <td>
              <img src="%s">
            </td>
            <td style="vertical-align: middle">
              <strong>tracked</strong>(registration result available)
            </td>
          </tr>
          <tr>
            <td>
              <img src="%s">
            </td>
            <td style="vertical-align: middle">
              <strong>untracked</strong>(no registration result available)
            </td>
          </tr>
          <tr>
            <td>
              <img src="%s">
            </td>
            <td style="vertical-align: middle">
              <strong>skipped</strong>(no registration result available)
            </td>
          </tr>
          <tr>
            <td style="vertical-align: middle">
              <img src="%s">
            </td>
            <td>
              <strong>rejected</strong>(non satisfactory/approved registration result available)
            </td>
          </tr>
        </tbody>
      </table>
    </body>
  </html>
  """ % (helper.createAndGetRawColoredPixelMap("green"), helper.createAndGetRawColoredPixelMap("yellow"),
         helper.createAndGetRawColoredPixelMap("red"), helper.createAndGetRawColoredPixelMap("grey"))
Пример #21
0
 def setupPreopLoadedTargets(self):
     targets = self.data.initialTargets
     ModuleWidgetMixin.setFiducialNodeVisibility(targets, show=True)
     self.applyDefaultTargetDisplayNode(targets)
     self.markupsLogic.JumpSlicesToNthPointInMarkup(targets.GetID(), 0)
Пример #22
0
 def addOldImageAnnotation(self, widget, text, size=20):
   self.oldImageAnnotation = SliceAnnotation(widget, text, yPos=35 if ModuleWidgetMixin.isQtVersionOlder() else 45,
                                             size=size)
   self.sliceAnnotations.append(self.oldImageAnnotation)
 def updateProgressBar(self, **kwargs):
   ModuleWidgetMixin.updateProgressBar(self, progress=self.progress, **kwargs)