mermin_core/cell.rs
1// mermin-core/src/cell.rs
2
3use crate::Real;
4use serde::{Deserialize, Serialize};
5
6/// Complete per-cell measurement record.
7/// Each field is filled progressively by different analysis stages.
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct CellRecord {
10 /// Unique cell label from segmentation mask.
11 pub label: i32,
12 /// Centroid position in physical coordinates (um).
13 pub centroid: [Real; 2],
14
15 // -- Shape (mermin-shape) --
16 /// Cell area in um^2.
17 pub area: Real,
18 /// Cell perimeter in um.
19 pub perimeter: Real,
20 /// Shape index p_0 = P / sqrt(A).
21 pub shape_index: Real,
22 /// Convexity = A / A_convex_hull.
23 pub convexity: Real,
24 /// Elongation magnitude from Minkowski W1^{1,1} tensor.
25 pub elongation: Real,
26 /// Elongation orientation angle in radians [0, pi).
27 pub elongation_angle: Real,
28 /// k-atic shape mode amplitudes |W1^{s,0}| / W0 for k = [1, 2, 4, 6].
29 pub shape_katic: [Real; 4],
30
31 // -- Orientation (mermin-orient) --
32 /// Per-cell mean internal alignment |psi_k| for k = [1, 2, 4, 6],
33 /// at the optimal scale sigma*.
34 pub internal_katic: [Real; 4],
35 /// Optimal structure tensor scale sigma* (pixels) where |psi_2| is maximized.
36 pub optimal_scale: Real,
37 /// Nuclear aspect ratio (major_axis / minor_axis from DAPI).
38 pub nuclear_aspect_ratio: Real,
39 /// Nuclear orientation angle in radians [0, pi).
40 pub nuclear_angle: Real,
41
42 // -- Topology (mermin-topo) --
43 /// Number of Delaunay neighbors.
44 pub n_neighbors: usize,
45}
46
47impl CellRecord {
48 /// Create a partially filled CellRecord with only label and centroid.
49 /// All other fields initialized to zero/default.
50 pub fn new(label: i32, centroid: [Real; 2]) -> Self {
51 Self {
52 label,
53 centroid,
54 area: 0.0,
55 perimeter: 0.0,
56 shape_index: 0.0,
57 convexity: 0.0,
58 elongation: 0.0,
59 elongation_angle: 0.0,
60 shape_katic: [0.0; 4],
61 internal_katic: [0.0; 4],
62 optimal_scale: 0.0,
63 nuclear_aspect_ratio: 0.0,
64 nuclear_angle: 0.0,
65 n_neighbors: 0,
66 }
67 }
68}