docstr: Populate and return a CPGridInfo based on two cell locations
docstr_tok: ["Populate","and","return","a","CPGridInfo","based","on","two","cell","locations"]
code: def build_grid_info(
      self,
      first_x,
      first_y,
      first_row,
      first_col,
      second_x,
      second_y,
      second_row,
      second_col,
      image_shape=None,
  ):
      """Populate and return a CPGridInfo based on two cell locations"""
      first_row, first_col = self.canonical_row_and_column(
          first_row, first_col
      )
      second_row, second_col = self.canonical_row_and_column(
          second_row, second_col
      )
      gridding = Grid()
      gridding.x_spacing = float(first_x - second_x) / float(
          first_col - second_col
      )
      gridding.y_spacing = float(first_y - second_y) / float(
          first_row - second_row
      )
      gridding.x_location_of_lowest_x_spot = int(
          first_x - first_col * gridding.x_spacing
      )
      gridding.y_location_of_lowest_y_spot = int(
          first_y - first_row * gridding.y_spacing
      )
      gridding.rows = self.grid_rows.value
      gridding.columns = self.grid_columns.value
      gridding.left_to_right = self.origin in (
          NUM_TOP_LEFT,
          NUM_BOTTOM_LEFT,
      )
      gridding.top_to_bottom = self.origin in (
          NUM_TOP_LEFT,
          NUM_TOP_RIGHT,
      )
      gridding.total_width = int(gridding.x_spacing * gridding.columns)
      gridding.total_height = int(gridding.y_spacing * gridding.rows)
  
      line_left_x = int(
          gridding.x_location_of_lowest_x_spot - gridding.x_spacing / 2
      )
      line_top_y = int(
          gridding.y_location_of_lowest_y_spot - gridding.y_spacing / 2
      )
      #
      # Make a 2 x columns array of x-coordinates of vertical lines (x0=x1)
      #
      gridding.vert_lines_x = numpy.tile(
          (
              numpy.arange(gridding.columns + 1) * gridding.x_spacing
              + line_left_x
          ),
          (2, 1),
      ).astype(int)
      #
      # Make a 2 x rows array of y-coordinates of horizontal lines (y0=y1)
      #
      gridding.horiz_lines_y = numpy.tile(
          (
              numpy.arange(gridding.rows + 1) * gridding.y_spacing
              + line_top_y
          ),
          (2, 1),
      ).astype(int)
      #
      # Make a 2x columns array of y-coordinates of vertical lines
      # all of which are from line_top_y to the bottom
      #
      gridding.vert_lines_y = numpy.transpose(
          numpy.tile(
              (line_top_y, line_top_y + gridding.total_height),
              (gridding.columns + 1, 1),
          )
      ).astype(int)
      gridding.horiz_lines_x = numpy.transpose(
          numpy.tile(
              (line_left_x, line_left_x + gridding.total_width),
              (gridding.rows + 1, 1),
          )
      ).astype(int)
      gridding.x_locations = (
          gridding.x_location_of_lowest_x_spot
          + numpy.arange(gridding.columns) * gridding.x_spacing
      ).astype(int)
      gridding.y_locations = (
          gridding.y_location_of_lowest_y_spot
          + numpy.arange(gridding.rows) * gridding.y_spacing
      ).astype(int)
      #
      # The spot table has the numbering for each spot in the grid
      #
      gridding.spot_table = (
          numpy.arange(gridding.rows * gridding.columns) + 1
      )
      if self.ordering == NUM_BY_COLUMNS:
          gridding.spot_table.shape = (gridding.rows, gridding.columns)
      else:
          gridding.spot_table.shape = (gridding.columns, gridding.rows)
          gridding.spot_table = numpy.transpose(gridding.spot_table)
      if self.origin in (NUM_BOTTOM_LEFT, NUM_BOTTOM_RIGHT):
          # Flip top and bottom
          gridding.spot_table = gridding.spot_table[::-1, :]
      if self.origin in (NUM_TOP_RIGHT, NUM_BOTTOM_RIGHT):
          # Flip left and right
          gridding.spot_table = gridding.spot_table[:, ::-1]
      if image_shape is not None:
          gridding.image_height = image_shape[0]
          gridding.image_width = image_shape[1]
      else:
          # guess the image shape by adding the same border to the right
          # and bottom that we have on the left and top
          top_edge = int(
              gridding.y_location_of_lowest_y_spot
              - gridding.y_spacing / 2
          )
          right_edge = int(
              gridding.x_location_of_lowest_x_spot
              - gridding.x_spacing / 2
          )
          gridding.image_height = (
              top_edge * 2 + gridding.y_spacing * gridding.rows
          )
          gridding.image_width = (
              right_edge * 2 + gridding.x_spacing * gridding.columns
          )
      return gridding
  
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 12 for calling the DefineGrid obj's underlying member method code with example usage: obj.build_grid_info(first_x, first_y, first_row, first_col, second_x, second_y, second_row, second_col, image_shape) and returns: gridding