Example #1
0
def gen_crypt_masks(exp, input_run_type, run_type):
  """Generate crypt masks based on nuclei density and EdU count

  Args:
      exp (string): name of experiment 
      input_run_type (str): cellprofiler pipeline output to use (merged, etc)
      run_type (str): name for current process ('crypt_mask')

  Returns:
      None
  """

  # get file paths
  nuc_objs_dir = config.get_cp_output_nuc_objs(exp, input_run_type)

  for nuc_path in helpers.list_im_files(nuc_objs_dir):

    # paths
    im_name = config.get_im_name(nuc_path)
    csv_path = config.get_extract_csv_nuc_outpath(exp, input_run_type, im_name)

    # read in image
    nuc_im = cv2.imread(nuc_path, cv2.IMREAD_ANYDEPTH)

    # dense nuclei
    kn_size = config.get_crypt_finder_dilate_kn_size('crypt_masks')
    min_area = config.get_crypt_finder_min_area('crypt_masks')
    nuc_dense, label_mask = dense_objects(nuc_im, kernel_size=kn_size, min_area=min_area)

    # filter by edu
    edu_thresh = expinfo.get_thresh_edu(exp)
    min_edu_num = config.get_crypt_finder_min_edu_num(run_type)
    im_data = pd.read_csv(csv_path)

    edu_pos_objs = thresh_edu_objects(im_data, edu_thresh)

    nuc_crypt = filter_crypts(nuc_dense, label_mask, edu_pos_objs, min_edu_num)
    
    # give nuclei in same crypt the same label
    nuc_labeled = label_mask.copy()
    nuc_labeled[nuc_crypt==0] = 0

    # convex hull on crypts
    # crypt_mask = chull_groups(nuc_labeled)

    # save images
    objs_fname = config.get_fpath_crypt_objs(exp, input_run_type, im_name)
    cv2.imwrite(objs_fname, nuc_crypt)

    label_fname = config.get_fpath_crypt_labels(exp, input_run_type, im_name)
    cv2.imwrite(label_fname, nuc_labeled)
Example #2
0
def measure_props_no_paneth(exp, run_type, drop=False):
  """Measure properties for all wells in a plate

  Args:
      exp (str): plate name
      run_type (str): analysis output to use for measurements
      drop (bool): whether to drop frames

  Returns:
      None
  """
  
  # measurement names
  crypt_measures = ['num_cells', 'num_edu', 'nuc_area', 'eccentricity', 
    'solidity', 'row', 'col', 'fld']
  
  well_num_measures = ['num_cells', 'num_edu', 'num_crypt_cells', 'num_crypt_edu', 
    'num_villus_cells', 'num_villus_edu']
  well_measures = well_num_measures + ['avg_eccentricity', 'avg_solidity', 'num_crypts']

  # output directories
  crypt_dir = config.get_cp_output_crypt_measure(exp, run_type)
  well_dir = config.get_cp_output_well_measure(exp, run_type)

  # create output directories
  if not os.path.exists(crypt_dir):
    os.makedirs(crypt_dir)
  if not os.path.exists(well_dir):
    os.makedirs(well_dir)

  rows = constants.get_96_rows()
  cols = constants.get_96_cols()

  if drop:
    im_csv_path = config.get_extract_csv_im_drop_inpath(exp, run_type)

  # label
  drop_label = config.get_csv_drop_label()

  # matrices of well-level measurements      
  well_mats = {k: np.zeros((len(rows), len(cols))) for k in well_measures}

  for r, row in enumerate(rows):
    for c, col in enumerate(cols):

      # store crypt-level measurements
      crypt_props = {k: [] for k in crypt_measures}

      # store well-level measurements
      well_nums = {k: [] for k in well_num_measures}

      # iterate over fields
      num_flds = expinfo.get_num_fields(exp)
      start = expinfo.get_field_start(exp)

      for fld in list(range(start, num_flds+start, 1)):

        im_name = config.build_im_name(exp, row, col, fld, 'dna')

        objs_path = config.get_fpath_crypt_objs(exp, run_type, im_name)
        label_path = config.get_fpath_crypt_labels(exp, run_type, im_name)
        im_data_path = config.get_extract_csv_nuc_outpath(exp, run_type, im_name)

        crypt_objs = cv2.imread(objs_path, cv2.IMREAD_ANYDEPTH)
        label_mask = cv2.imread(label_path, cv2.IMREAD_ANYDEPTH)

        im_data = pd.read_csv(im_data_path)

        edu_thresh = expinfo.get_thresh_edu(exp)
        
        edu_objs = thresh_edu_objects(im_data, edu_thresh)

        # crypt-level measurements
        crypt_props = measure_crypts_props_no_paneth(crypt_objs, label_mask, edu_objs, crypt_props, row, col, fld)

        # well-level measurements
        well_props = {
          'num_cells': len(im_data),
          'num_edu': len(edu_objs),
          'num_crypt_cells': len(nonzero_unique(crypt_objs)),
          'num_crypt_edu': count_stained_objs(crypt_objs, edu_objs),
          'row': row,
          'col': col,
          'fld': fld
          }

        well_props.update({
          'num_villus_cells': well_props['num_cells'] - well_props['num_crypt_cells'],
          'num_villus_edu': well_props['num_edu'] - well_props['num_crypt_edu']
          })

        for k in list(well_nums.keys()):
          well_nums[k].append(well_props[k])

        for k in list(well_nums.keys()):
          well_nums[k].append(well_props[k])

      # save well-level measurements
      for k in well_num_measures:
        well_mats[k][r][c] = np.sum(well_nums[k])

      well_mats['avg_eccentricity'][r][c] = np.mean(crypt_props['eccentricity'])
      well_mats['avg_solidity'][r][c] = np.mean(crypt_props['solidity'])
      well_mats['num_crypts'][r][c] = len(crypt_props['num_cells'])

      # write crypt-level measurements to file
      well_name = config.build_well_name(row, col)
      out_path = config.get_fpath_crypt_measure(exp, run_type, well_name)

      helpers.dict_to_csv(out_path, crypt_props)

  # write well-level measurements to file
  for k in list(well_mats.keys()):
    out_path = config.get_fpath_well_measure(exp, run_type, k)
    np.savetxt(out_path, well_mats[k], delimiter=',')
Example #3
0
def measure_dispersion(exp, run_type, drop=False):
  """Measure properties for all wells in a plate

  Args:
      exp (str): plate name
      run_type (str): analysis output to use for measurements
      drop (bool): whether to drop frames

  Returns:
      None
  """

  # output directories
  well_dir = config.get_cp_output_well_measure(exp, run_type)

  # create output directories
  if not os.path.exists(well_dir):
    os.makedirs(well_dir)

  rows = constants.get_96_rows()
  cols = constants.get_96_cols()

  if drop:
    im_csv_path = config.get_extract_csv_im_drop_inpath(exp, run_type)

  # label
  drop_label = config.get_csv_drop_label()

  rows = ['A', 'B', 'C', 'D']
  cols = [1,2, 5]

  # measurement names
  well_disp = pd.DataFrame()

  for r, row in enumerate(rows):
    for c, col in enumerate(cols):

      # wellname
      well_name = config.build_well_name(row, col)

      # store crypt-level measurements
      crypt_disp = []

      # iterate over fields
      num_flds = expinfo.get_num_fields(exp)
      start = expinfo.get_field_start(exp)

      for fld in list(range(start, num_flds+start, 1)):

        im_name = config.build_im_name(exp, row, col, fld, 'dna')
        

        objs_path = config.get_fpath_crypt_objs(exp, run_type, im_name)
        label_path = config.get_fpath_crypt_labels(exp, run_type, im_name)
        im_data_path = config.get_extract_csv_nuc_outpath(exp, run_type, im_name)

        crypt_objs = cv2.imread(objs_path, cv2.IMREAD_ANYDEPTH)
        label_mask = cv2.imread(label_path, cv2.IMREAD_ANYDEPTH)

        im_data = pd.read_csv(im_data_path)

        edu_thresh = expinfo.get_thresh_edu(exp)
        
        edu_objs = thresh_edu_objects(im_data, edu_thresh)

        # list of crypt labels
        crypt_labels = nonzero_unique(label_mask)

        for l in crypt_labels:

          # measure properties for one crypt
          crypt_mask = get_object(label_mask, l)
          objs = mask_objects(crypt_objs, crypt_mask, mask_val=l)

          # add properties to dataframe
          edu_dist = measure_objs_dispersion(objs, edu_objs)

          # add data to dataframe
          if edu_dist is not None:
            crypt_disp = pd.DataFrame([{'d_nn': d, 'crypt_num': l, 'well': well_name} for d in edu_dist])
            well_disp = well_disp.append(crypt_disp)
            
  out_path = config.get_fpath_well_measure(exp, run_type, 'edu_dispersion')
  well_disp.to_csv(out_path, index=False)
  print(out_path)