def get_fft_coefs(input_dir, num_points=500, num_coefs=20): """ Calculate the Fourier shape descriptors from the saved cell contours. args: df (DataFrame): contains requested coordinates and trajectories """ # Read the necessary variables in from file df = read.makedataframe(input_dir, ('EdgeSpline', )) df['FourierCoef'] = None # Evaluate each frame independently u = np.arange(0., 1., 1. / num_points) for i, v in enumerate(df.index): tck = df['EdgeSpline'].ix[v] try: xs = splineprops(u, tck, 'Coordinates')['Coordinates'] d = fftcoefs(xs, n=num_coefs) except Exception: d = {} df['FourierCoef'].ix[v] = d # Save new Series to file df['FourierCoef'].to_pickle(os.path.join(input_dir, 'FourierCoef.pickle'))
def get_fft_coefs(input_dir, num_points=500, num_coefs=20): """ Calculate the Fourier shape descriptors from the saved cell contours. args: df (DataFrame): contains requested coordinates and trajectories """ # Read the necessary variables in from file df = read.makedataframe(input_dir, ("EdgeSpline",)) df["FourierCoef"] = None # Evaluate each frame independently u = np.arange(0.0, 1.0, 1.0 / num_points) for i, v in enumerate(df.index): tck = df["EdgeSpline"].ix[v] try: xs = splineprops(u, tck, "Coordinates")["Coordinates"] d = fftcoefs(xs, n=num_coefs) except Exception: d = {} df["FourierCoef"].ix[v] = d # Save new Series to file df["FourierCoef"].to_pickle(os.path.join(input_dir, "FourierCoef.pickle"))
def split_areas(u, tck, z, xs, ps, a): """ Find the areas of the parent and nascent daughter cells. args: u (ndarray): 1D array giving paramaterization of the spline z (ndarray): coordinates of division plane on midline tck (list): spline representation of border xs (ndarray): coordinates along the border ps (ndarray): coordinates of cell poles a (float): area of the entire cell returns: ao (float): area of the parent cell an (float): area of the daughter cell """ # Split the border into two contours, one for each new cell uo, un = splitborder(u, xs, z) # Identify the contours with the old and new cells xso = np.asarray(zip(*splev(uo, tck))) xsn = np.asarray(zip(*splev(un, tck))) # Verify the identifications po, pn = ps do = np.min([norm(po - v) for v in xso]) dn = np.min([norm(pn - v) for v in xso]) if dn < do: xso, xsn = xsn, xso # Make new periodic splines for each cell tcko = makebspline(xso, 0., True)[0] tckn = makebspline(xsn, 0., True)[0] # Return the area of each cell ao = splineprops(u, tcko, ('Area', ))['Area'] an = splineprops(u, tckn, ('Area', ))['Area'] # Scale the results to be commensurate with the full area f = a / (ao + an) return f * ao, f * an
def split_areas(u, tck, z, xs, ps, a): """ Find the areas of the parent and nascent daughter cells. args: u (ndarray): 1D array giving paramaterization of the spline z (ndarray): coordinates of division plane on midline tck (list): spline representation of border xs (ndarray): coordinates along the border ps (ndarray): coordinates of cell poles a (float): area of the entire cell returns: ao (float): area of the parent cell an (float): area of the daughter cell """ # Split the border into two contours, one for each new cell uo, un = splitborder(u, xs, z) # Identify the contours with the old and new cells xso = np.asarray(zip(*splev(uo, tck))) xsn = np.asarray(zip(*splev(un, tck))) # Verify the identifications po, pn = ps do = np.min([norm(po - v) for v in xso]) dn = np.min([norm(pn - v) for v in xso]) if dn < do: xso, xsn = xsn, xso # Make new periodic splines for each cell tcko = makebspline(xso, 0.0, True)[0] tckn = makebspline(xsn, 0.0, True)[0] # Return the area of each cell ao = splineprops(u, tcko, ("Area",))["Area"] an = splineprops(u, tckn, ("Area",))["Area"] # Scale the results to be commensurate with the full area f = a / (ao + an) return f * ao, f * an
def split_lengths(u, tck, j_min, xs, ps, l): """ Find the lengths of the parent and nascent daughter cells. args: u (ndarray): 1D array giving paramaterization of the spline j_min (ndarray): index of division plane on midline tck (list): spline representation of midline xs (ndarray): coordinates along the midline ps (ndarray): coordinates of cell poles l (float): length of the entire cell returns: lo (float): length of the parent cell ln (float): length of the daughter cell """ # Split the midline around the division plane uo, un = u[:j_min + 1], u[j_min:] # Verify the identifications po, pn = ps xo = splev(uo[0], tck) do = np.min(norm(po - xo)) dn = np.min(norm(pn - xo)) if dn < do: uo, un = un, uo # Return the lengths of each cell lo = splineprops(uo, tck, ('Length', ))['Length'] ln = splineprops(un, tck, ('Length', ))['Length'] # Scale the results to be commensurate with the full length f = l / (lo + ln) return f * lo, f * ln
def split_lengths(u, tck, j_min, xs, ps, l): """ Find the lengths of the parent and nascent daughter cells. args: u (ndarray): 1D array giving paramaterization of the spline j_min (ndarray): index of division plane on midline tck (list): spline representation of midline xs (ndarray): coordinates along the midline ps (ndarray): coordinates of cell poles l (float): length of the entire cell returns: lo (float): length of the parent cell ln (float): length of the daughter cell """ # Split the midline around the division plane uo, un = u[: j_min + 1], u[j_min:] # Verify the identifications po, pn = ps xo = splev(uo[0], tck) do = np.min(norm(po - xo)) dn = np.min(norm(pn - xo)) if dn < do: uo, un = un, uo # Return the lengths of each cell lo = splineprops(uo, tck, ("Length",))["Length"] ln = splineprops(un, tck, ("Length",))["Length"] # Scale the results to be commensurate with the full length f = l / (lo + ln) return f * lo, f * ln
def get_width_profile_new(s, num_points=500): """ Get the width profile and associated variables with a recalculated midline. args: s (Series): data read in from file for a single frame returns: d (dict): calculated values """ # Evaluate the midline at discrete points starting at the old pole u = np.linspace(0., 1., num_points) d = { 'Radius': np.nan, 'RadiusStalked': np.nan, 'RadiusSwarmer': np.nan, 'Widths': np.empty(0), 'WidthMin': np.nan, 'WidthStalkedMax': np.nan, 'WidthSwarmerMax': np.nan, 'WidthStalkedMin': np.nan, 'WidthSwarmerMin': np.nan, 'Area': np.nan, 'AreaStalked': np.nan, 'AreaSwarmer': np.nan, 'Length': np.nan, 'LengthStalked': np.nan, 'LengthSwarmer': np.nan, 'LengthStalkedMin': np.nan, 'LengthSwarmerMin': np.nan, 'MidSpline': [] } try: # Get coordinates and first derivative of contour tck = s['EdgeSpline'] es = np.asarray(zip(*splev(u, tck))) des = np.asarray(zip(*splev(u, tck, der=1))) # Find a crude approximation of the cell poles ps = (s['StalkedPole'], s['SwarmerPole']) # Approximate the midline by taking the Voronoi diagram vs = find_midline(es) # Prune the Voronoi diagram to remove branch points cs0 = prune_midline(es, des, vs) # Reorient the midline from stalked to swarmer pole cs1 = orient_midline(es, cs0, ps) # Find approximate width along the medial axis ws1 = get_width(es, cs1[:-1], np.diff(cs1, axis=0)) # Find the radius of curvature of the entire cell cre0 = fit_circle(cs1) # Get the minimum cell width j1_min, w1_min = find_min_width(ws1) if np.any(j1_min): # Split contours according to minimum cell width wso1, wsn1 = ws1[:j1_min], ws1[j1_min:] # Find the maximum widths of either side jo1_max, wo1_max = find_max_width(wso1) jn1_max, wn1_max = find_max_width(wsn1) # Only keep exterior points within 98% of maximum width ko1_max = np.flatnonzero(wso1[jo1_max:] > wo1_max * 0.75) ko1 = np.hstack((range(jo1_max), jo1_max + ko1_max)) kn1_max = np.flatnonzero(wsn1[:jn1_max] > wn1_max * 0.75) kn1 = np.hstack((kn1_max, range(jn1_max, len(wsn1)))) # Fit circles to either cell cre1 = fit_circle(cs1[ko1]) cre2 = fit_circle(cs1[j1_min + kn1]) else: cre1, cre2, = cre0, cre0 # Extend the midline in a way that maintains curvature cs2 = extend_midline(es, cs1, (cre1[:2], cre2[:2]), ps) # Spline the new midline tck4 = makebspline(cs2, smoothing=0.1)[0] d['MidSpline'] = tck4 cs4 = np.asarray(zip(*splev(u, tck4))) dcs4 = np.asarray(zip(*splev(u, tck4, der=1))) # Get the correct cell poles po, pn = cs4[0], cs4[-1] # Get the index of the stalked pole jo = np.argmin(np.sum((es - po)**2, axis=1)) # Overall cell area and length a = splineprops(u, tck, 'Area')['Area'] d['Area'] = a l = splineprops(u, tck4, 'Length')['Length'] d['Length'] = l # Fit best-fit circle to entire cell cre0 = fit_circle(cs4) d['Radius'] = cre0[1] # Get the cell width and minimum and maximum cell widths ws4 = get_width(es, cs4, dcs4) d['Widths'] = ws4 j4_min, w_min = find_min_width(ws4) d['WidthMin'] = w_min if np.any(j4_min): # Split contours according to minimum cell width wso4, wsn4 = ws4[:j4_min], ws4[j4_min:] # Find the maximum widths of either side jo4_max, wo_max = find_max_width(wso4) jn4_max, wn_max = find_max_width(wsn4) # Find the minimum widths of either side jo4_min, wo_min = find_min_width(wso4) jn4_min, wn_min = find_min_width(wsn4) if not np.any(jo4_min): jo4_min = np.nan if not np.any(jn4_min): jn4_min = np.nan # Get points on contour at division plane es_min = get_divn_plane(es, cs4[j4_min], dcs4[j4_min]) # Split the cell areas and lengths ao, an = split_areas(u, tck, es_min, es, (po, pn), a) lo, ln = split_lengths(u, tck4, j4_min, es, (po, pn), l) # Find the lengths to either secondary minimum ro_min = float(jo4_min) / float(len(wso4)) rn_min = 1. - float(jn4_min) / float(len(wsn4)) lo_min = lo * ro_min ln_min = ln * rn_min # Find best-fit circle to each cell half cre1 = fit_circle(cs4[:j4_min]) cre2 = fit_circle(cs4[j4_min:]) else: wo_max, wn_max = np.nan, np.nan wo_min, wn_min = np.nan, np.nan ao, an = np.nan, np.nan lo, ln = np.nan, np.nan cre1 = (np.nan, np.nan) cre2 = (np.nan, np.nan) lo_min, ln_min = np.nan, np.nan d['RadiusStalked'] = cre1[1] d['RadiusSwarmer'] = cre2[1] d['WidthStalkedMax'] = wo_max d['WidthSwarmerMax'] = wn_max d['WidthStalkedMin'] = wo_min d['WidthSwarmerMin'] = wn_min d['AreaStalked'] = ao d['AreaSwarmer'] = an d['LengthStalked'] = lo d['LengthSwarmer'] = ln d['LengthStalkedMin'] = lo_min d['LengthSwarmerMin'] = ln_min except Exception: pass return d
def get_length(u, tck): return splineprops(u, tck, ('Length', ))['Length']
def get_width_profile_new(s, num_points=500): """ Get the width profile and associated variables with a recalculated midline. args: s (Series): data read in from file for a single frame returns: d (dict): calculated values """ # Evaluate the midline at discrete points starting at the old pole u = np.linspace(0.0, 1.0, num_points) d = { "Radius": np.nan, "RadiusStalked": np.nan, "RadiusSwarmer": np.nan, "Widths": np.empty(0), "WidthMin": np.nan, "WidthStalkedMax": np.nan, "WidthSwarmerMax": np.nan, "WidthStalkedMin": np.nan, "WidthSwarmerMin": np.nan, "Area": np.nan, "AreaStalked": np.nan, "AreaSwarmer": np.nan, "Length": np.nan, "LengthStalked": np.nan, "LengthSwarmer": np.nan, "LengthStalkedMin": np.nan, "LengthSwarmerMin": np.nan, "MidSpline": [], } try: # Get coordinates and first derivative of contour tck = s["EdgeSpline"] es = np.asarray(zip(*splev(u, tck))) des = np.asarray(zip(*splev(u, tck, der=1))) # Find a crude approximation of the cell poles ps = (s["StalkedPole"], s["SwarmerPole"]) # Approximate the midline by taking the Voronoi diagram vs = find_midline(es) # Prune the Voronoi diagram to remove branch points cs0 = prune_midline(es, des, vs) # Reorient the midline from stalked to swarmer pole cs1 = orient_midline(es, cs0, ps) # Find approximate width along the medial axis ws1 = get_width(es, cs1[:-1], np.diff(cs1, axis=0)) # Find the radius of curvature of the entire cell cre0 = fit_circle(cs1) # Get the minimum cell width j1_min, w1_min = find_min_width(ws1) if np.any(j1_min): # Split contours according to minimum cell width wso1, wsn1 = ws1[:j1_min], ws1[j1_min:] # Find the maximum widths of either side jo1_max, wo1_max = find_max_width(wso1) jn1_max, wn1_max = find_max_width(wsn1) # Only keep exterior points within 98% of maximum width ko1_max = np.flatnonzero(wso1[jo1_max:] > wo1_max * 0.75) ko1 = np.hstack((range(jo1_max), jo1_max + ko1_max)) kn1_max = np.flatnonzero(wsn1[:jn1_max] > wn1_max * 0.75) kn1 = np.hstack((kn1_max, range(jn1_max, len(wsn1)))) # Fit circles to either cell cre1 = fit_circle(cs1[ko1]) cre2 = fit_circle(cs1[j1_min + kn1]) else: cre1, cre2, = cre0, cre0 # Extend the midline in a way that maintains curvature cs2 = extend_midline(es, cs1, (cre1[:2], cre2[:2]), ps) # Spline the new midline tck4 = makebspline(cs2, smoothing=0.1)[0] d["MidSpline"] = tck4 cs4 = np.asarray(zip(*splev(u, tck4))) dcs4 = np.asarray(zip(*splev(u, tck4, der=1))) # Get the correct cell poles po, pn = cs4[0], cs4[-1] # Get the index of the stalked pole jo = np.argmin(np.sum((es - po) ** 2, axis=1)) # Overall cell area and length a = splineprops(u, tck, "Area")["Area"] d["Area"] = a l = splineprops(u, tck4, "Length")["Length"] d["Length"] = l # Fit best-fit circle to entire cell cre0 = fit_circle(cs4) d["Radius"] = cre0[1] # Get the cell width and minimum and maximum cell widths ws4 = get_width(es, cs4, dcs4) d["Widths"] = ws4 j4_min, w_min = find_min_width(ws4) d["WidthMin"] = w_min if np.any(j4_min): # Split contours according to minimum cell width wso4, wsn4 = ws4[:j4_min], ws4[j4_min:] # Find the maximum widths of either side jo4_max, wo_max = find_max_width(wso4) jn4_max, wn_max = find_max_width(wsn4) # Find the minimum widths of either side jo4_min, wo_min = find_min_width(wso4) jn4_min, wn_min = find_min_width(wsn4) if not np.any(jo4_min): jo4_min = np.nan if not np.any(jn4_min): jn4_min = np.nan # Get points on contour at division plane es_min = get_divn_plane(es, cs4[j4_min], dcs4[j4_min]) # Split the cell areas and lengths ao, an = split_areas(u, tck, es_min, es, (po, pn), a) lo, ln = split_lengths(u, tck4, j4_min, es, (po, pn), l) # Find the lengths to either secondary minimum ro_min = float(jo4_min) / float(len(wso4)) rn_min = 1.0 - float(jn4_min) / float(len(wsn4)) lo_min = lo * ro_min ln_min = ln * rn_min # Find best-fit circle to each cell half cre1 = fit_circle(cs4[:j4_min]) cre2 = fit_circle(cs4[j4_min:]) else: wo_max, wn_max = np.nan, np.nan wo_min, wn_min = np.nan, np.nan ao, an = np.nan, np.nan lo, ln = np.nan, np.nan cre1 = (np.nan, np.nan) cre2 = (np.nan, np.nan) lo_min, ln_min = np.nan, np.nan d["RadiusStalked"] = cre1[1] d["RadiusSwarmer"] = cre2[1] d["WidthStalkedMax"] = wo_max d["WidthSwarmerMax"] = wn_max d["WidthStalkedMin"] = wo_min d["WidthSwarmerMin"] = wn_min d["AreaStalked"] = ao d["AreaSwarmer"] = an d["LengthStalked"] = lo d["LengthSwarmer"] = ln d["LengthStalkedMin"] = lo_min d["LengthSwarmerMin"] = ln_min except Exception: pass return d
def get_length(u, tck): return splineprops(u, tck, ("Length",))["Length"]