docstr: Define a grid by running the UI
  
  Returns a CPGridInfo object
docstr_tok: ["Define","a","grid","by","running","the","UI","Returns","a","CPGridInfo","object"]
code: def run_mouse(self, background_image, image_set_number):
      """Define a grid by running the UI
  
      Returns a CPGridInfo object
      """
      import matplotlib
      import matplotlib.backends.backend_wxagg as backend
      import wx
      from wx.lib.intctrl import IntCtrl
  
      #
      # Make up a dialog box. It has the following structure:
      #
      # Dialog:
      #    top_sizer:
      #        Canvas
      #            Figure
      #               Axis
      #        control_sizer
      #            first_sizer
      #               first_row
      #               first_col
      #            second_sizer
      #               second_row
      #               second_col
      #            button_sizer
      #               Redisplay
      #               OK
      #               cancel
      #    status bar
      #
      figure = matplotlib.figure.Figure()
      frame = wx.Dialog(
          wx.GetApp().TopWindow,
          title="Select grid cells, image cycle #%d:"
          % (image_set_number),
      )
      top_sizer = wx.BoxSizer(wx.VERTICAL)
      frame.SetSizer(top_sizer)
      canvas = backend.FigureCanvasWxAgg(frame, -1, figure)
      top_sizer.Add(canvas, 1, wx.EXPAND)
      top_sizer.Add(
          wx.StaticText(
              frame,
              -1,
              "Select the center of a grid cell with the left mouse button.\n",
          ),
          0,
          wx.EXPAND | wx.ALL,
          5,
      )
      control_sizer = wx.BoxSizer(wx.HORIZONTAL)
      top_sizer.Add(control_sizer, 0, wx.EXPAND | wx.ALL, 5)
      FIRST_CELL = "First cell"
      SECOND_CELL = "Second cell"
      cell_choice = wx.RadioBox(
          frame,
          label="Choose current cell",
          choices=[FIRST_CELL, SECOND_CELL],
          style=wx.RA_VERTICAL,
      )
      control_sizer.Add(cell_choice)
      #
      # Text boxes for the first cell's row and column
      #
      first_sizer = wx.GridBagSizer(2, 2)
      control_sizer.Add(first_sizer, 1, wx.EXPAND | wx.ALL, 5)
      first_sizer.Add(
          wx.StaticText(frame, -1, "First cell column:"),
          wx.GBPosition(0, 0),
          flag=wx.EXPAND,
      )
      first_column = IntCtrl(
          frame, -1, 1, min=1, max=self.grid_columns.value
      )
      first_sizer.Add(first_column, wx.GBPosition(0, 1), flag=wx.EXPAND)
      first_sizer.Add(
          wx.StaticText(frame, -1, "First cell row:"),
          wx.GBPosition(1, 0),
          flag=wx.EXPAND,
      )
      first_row = IntCtrl(frame, -1, 1, min=1, max=self.grid_rows.value)
      first_sizer.Add(first_row, wx.GBPosition(1, 1), flag=wx.EXPAND)
      first_sizer.Add(
          wx.StaticText(frame, -1, "X:"), wx.GBPosition(0, 2)
      )
      first_x = IntCtrl(frame, -1, 100, min=1)
      first_sizer.Add(first_x, wx.GBPosition(0, 3))
      first_sizer.Add(
          wx.StaticText(frame, -1, "Y:"), wx.GBPosition(1, 2)
      )
      first_y = IntCtrl(frame, -1, 100, min=1)
      first_sizer.Add(first_y, wx.GBPosition(1, 3))
      #
      # Text boxes for the second cell's row and column
      #
      second_sizer = wx.GridBagSizer(2, 2)
      control_sizer.Add(second_sizer, 1, wx.EXPAND | wx.ALL, 5)
      second_sizer.Add(
          wx.StaticText(frame, -1, "Second cell column:"),
          wx.GBPosition(0, 0),
          flag=wx.EXPAND,
      )
      second_column = IntCtrl(
          frame,
          -1,
          self.grid_columns.value,
          min=1,
          max=self.grid_columns.value,
      )
      second_sizer.Add(
          second_column, wx.GBPosition(0, 1), flag=wx.EXPAND
      )
      second_sizer.Add(
          wx.StaticText(frame, -1, "Second cell row:"),
          wx.GBPosition(1, 0),
          flag=wx.EXPAND,
      )
      second_row = IntCtrl(
          frame,
          -1,
          self.grid_rows.value,
          min=1,
          max=self.grid_rows.value,
      )
      second_sizer.Add(second_row, wx.GBPosition(1, 1), flag=wx.EXPAND)
      second_sizer.Add(
          wx.StaticText(frame, -1, "X:"), wx.GBPosition(0, 2)
      )
      second_x = IntCtrl(frame, -1, 200, min=1)
      second_sizer.Add(second_x, wx.GBPosition(0, 3))
      second_sizer.Add(
          wx.StaticText(frame, -1, "Y:"), wx.GBPosition(1, 2)
      )
      second_y = IntCtrl(frame, -1, 200, min=1)
      second_sizer.Add(second_y, wx.GBPosition(1, 3))
      #
      # Buttons
      #
      button_sizer = wx.BoxSizer(wx.VERTICAL)
      control_sizer.Add(button_sizer, 0, wx.EXPAND | wx.ALL, 5)
      redisplay_button = wx.Button(frame, -1, "Redisplay")
      button_sizer.Add(redisplay_button)
      button_sizer.Add(wx.Button(frame, wx.OK, "OK"))
      button_sizer.Add(wx.Button(frame, wx.CANCEL, "Cancel"))
      #
      # Status bar
      #
      status_bar = wx.StatusBar(frame, style=0)
      top_sizer.Add(status_bar, 0, wx.EXPAND)
      status_bar.SetFieldsCount(1)
      SELECT_FIRST_CELL = "Select the center of the first cell"
      SELECT_SECOND_CELL = "Select the center of the second cell"
      status_bar.SetStatusText(SELECT_FIRST_CELL)
      status = [wx.OK]
      gridding = [None]
      if self.display_image_name == "Leave blank":
          image_shape = None
      else:
          image_shape = background_image.shape[:2]
  
      def redisplay(event):
          figure.clf()
          axes = figure.add_subplot(1, 1, 1)
  
          if (event is not None) or (gridding[0] is None):
              do_gridding(
                  first_x.GetValue(),
                  first_y.GetValue(),
                  second_x.GetValue(),
                  second_y.GetValue(),
              )
          self.display_grid(
              background_image, gridding[0], image_set_number, axes
          )
          canvas.draw()
  
      def cancel(event):
          status[0] = wx.CANCEL
          frame.SetReturnCode(wx.CANCEL)
          frame.Close(True)
  
      def ok(event):
          status[0] = wx.OK
          frame.SetReturnCode(wx.OK)
          frame.Close(True)
  
      def on_cell_selection(event):
          if cell_choice.GetSelection() == 0:
              status_bar.SetStatusText(SELECT_FIRST_CELL)
          else:
              status_bar.SetStatusText(SELECT_SECOND_CELL)
  
      def do_gridding(x1, y1, x2, y2):
          try:
              gridding[0] = self.build_grid_info(
                  int(x1),
                  int(y1),
                  int(first_row.GetValue()),
                  int(first_column.GetValue()),
                  int(x2),
                  int(y2),
                  int(second_row.GetValue()),
                  int(second_column.GetValue()),
                  image_shape,
              )
          except Exception as e:
              LOGGER.error(e, exc_info=True)
              status_bar.SetStatusText(str(e))
              return False
          return True
  
      def button_release(event):
          if event.inaxes == figure.axes[0]:
              if cell_choice.GetSelection() == 0:
                  new_first_x = str(int(event.xdata))
                  new_first_y = str(int(event.ydata))
                  if do_gridding(
                      new_first_x,
                      new_first_y,
                      second_x.GetValue(),
                      second_y.GetValue(),
                  ):
                      first_x.SetValue(new_first_x)
                      first_y.SetValue(new_first_y)
                      cell_choice.SetSelection(1)
                      status_bar.SetStatusText(SELECT_SECOND_CELL)
              else:
                  new_second_x = str(int(event.xdata))
                  new_second_y = str(int(event.ydata))
                  if do_gridding(
                      first_x.GetValue(),
                      first_y.GetValue(),
                      new_second_x,
                      new_second_y,
                  ):
                      second_x.SetValue(new_second_x)
                      second_y.SetValue(new_second_y)
                      cell_choice.SetSelection(0)
                      status_bar.SetStatusText(SELECT_FIRST_CELL)
              redisplay(None)
  
      redisplay(None)
      frame.Fit()
      frame.Bind(wx.EVT_BUTTON, redisplay, redisplay_button)
      frame.Bind(wx.EVT_BUTTON, cancel, id=wx.CANCEL)
      frame.Bind(wx.EVT_BUTTON, ok, id=wx.OK)
      frame.Bind(wx.EVT_RADIOBOX, on_cell_selection, cell_choice)
      canvas.mpl_connect("button_release_event", button_release)
      frame.ShowModal()
      do_gridding(
          first_x.GetValue(),
          first_y.GetValue(),
          second_x.GetValue(),
          second_y.GetValue(),
      )
      frame.Destroy()
      if status[0] != wx.OK:
          raise RuntimeError("Pipeline aborted during grid editing")
      return gridding[0]
  
imports: import logging
  import centrosome.cpmorphology
  import numpy
  from cellprofiler_core.constants.measurement import COLTYPE_FLOAT
  from cellprofiler_core.constants.measurement import COLTYPE_INTEGER
  from cellprofiler_core.constants.measurement import IMAGE
  from cellprofiler_core.image import Image
  from cellprofiler_core.module import Module
  from cellprofiler_core.setting import Binary
  from cellprofiler_core.setting import Coordinates
  from cellprofiler_core.setting import ValidationError
  from cellprofiler_core.setting.choice import Choice
  from cellprofiler_core.setting.subscriber import ImageSubscriber
  from cellprofiler_core.setting.subscriber import LabelSubscriber
  from cellprofiler_core.setting.text import GridName
  from cellprofiler_core.setting.text import ImageName
  from cellprofiler_core.setting.text import Integer
  from cellprofiler_core.utilities.grid import Grid
label_desc: Use image node_id 9 for calling the DefineGrid obj's underlying member method code with example usage: obj.run_mouse(background_image, image_set_number) and returns: gridding, True, False