diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..8d09aa3 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-08-13 - [SWIG Exception Overhead in CC3D Spatial Loops] +**Learning:** In CompuCell3D (CC3D) Python scripts, using try...except blocks inside tightly nested spatial loops for field accesses (like self.cell_field) incurs significant overhead because out-of-bounds SWIG object lookups throw expensive exceptions. +**Action:** Always use explicit boundary checks (e.g., comparing against self.dim.x and self.dim.y) before accessing arrays instead of relying on try-except blocks for boundary handling. diff --git a/Simulation/CancerInvasionSteppables.py b/Simulation/CancerInvasionSteppables.py index 3782ab5..134a70a 100644 --- a/Simulation/CancerInvasionSteppables.py +++ b/Simulation/CancerInvasionSteppables.py @@ -89,13 +89,11 @@ def initialize_paper_ecm(self): pixels_assigned = 0 for x, y in fiber_pixels: - try: + if 0 <= x < self.dim.x and 0 <= y < self.dim.y: if self.cell_field[x, y, 0] is None: self.cell_field[x, y, 0] = fiber_cell self.fiber_locations.add((x, y)) pixels_assigned += 1 - except: - continue if pixels_assigned >= 10: fibers_created += 1 @@ -175,13 +173,10 @@ def create_paper_cell(self, center_x, center_y, radius): for dy in range(-radius, radius + 1): if dx*dx + dy*dy <= radius*radius: px, py = center_x + dx, center_y + dy - if 0 <= px < 500 and 0 <= py < 500: - try: - if self.cell_field[px, py, 0] is None: - self.cell_field[px, py, 0] = cell - pixels_added += 1 - except: - continue + if 0 <= px < self.dim.x and 0 <= py < self.dim.y: + if self.cell_field[px, py, 0] is None: + self.cell_field[px, py, 0] = cell + pixels_added += 1 if pixels_added >= 20: return True @@ -210,12 +205,9 @@ def safe_cell_removal(self, cell): min(self.dim.x, int(cell.xCOM) + search_radius)): for y in range(max(0, int(cell.yCOM) - search_radius), min(self.dim.y, int(cell.yCOM) + search_radius)): - try: - if self.cell_field[x, y, 0] == cell: - self.cell_field[x, y, 0] = None - pixels_cleared += 1 - except: - continue + if self.cell_field[x, y, 0] == cell: + self.cell_field[x, y, 0] = None + pixels_cleared += 1 return pixels_cleared > 0 except Exception as e: return False @@ -285,16 +277,13 @@ def paper_mmp_system(self): fibers_to_remove = [] for cell in self.cell_list: if cell.type == self.ECMFIBER: - try: - cx, cy = int(cell.xCOM), int(cell.yCOM) - if 0 <= cx < 500 and 0 <= cy < 500: - mmp_conc = mmp_field[cx, cy, 0] - if mmp_conc >= self.degradation_threshold: - fibers_to_remove.append(cell) - # Paper: reduce MMP count by 1 after degradation - mmp_field[cx, cy, 0] = max(0, mmp_conc - 1) - except: - continue + cx, cy = int(cell.xCOM), int(cell.yCOM) + if 0 <= cx < self.dim.x and 0 <= cy < self.dim.y: + mmp_conc = mmp_field[cx, cy, 0] + if mmp_conc >= self.degradation_threshold: + fibers_to_remove.append(cell) + # Paper: reduce MMP count by 1 after degradation + mmp_field[cx, cy, 0] = max(0, mmp_conc - 1) # Remove degraded fibers for fiber in fibers_to_remove: @@ -312,13 +301,10 @@ def check_ecm_contact(self, cell): for dx in range(-3, 4): for dy in range(-3, 4): nx, ny = cx + dx, cy + dy - if 0 <= nx < 500 and 0 <= ny < 500: - try: - neighbor = self.cell_field[nx, ny, 0] - if neighbor and neighbor.type == self.ECMFIBER: - return True - except: - continue + if 0 <= nx < self.dim.x and 0 <= ny < self.dim.y: + neighbor = self.cell_field[nx, ny, 0] + if neighbor and neighbor.type == self.ECMFIBER: + return True return False except: return False @@ -371,11 +357,12 @@ def step(self, mcs): contact_area += commonSurfaceArea if contact_area < self.crowding_threshold: - try: - mmp_conc = self.field.MMP[int(cell.xCOM), int(cell.yCOM), 0] + cx, cy = int(cell.xCOM), int(cell.yCOM) + if 0 <= cx < self.dim.x and 0 <= cy < self.dim.y: + mmp_conc = self.field.MMP[cx, cy, 0] growth_boost = 1.0 + (mmp_conc * 0.1) cell.targetVolume += self.growth_rate * growth_boost - except: + else: cell.targetVolume += self.growth_rate diff --git a/Simulation/__pycache__/CancerInvasionSteppables.cpython-312.pyc b/Simulation/__pycache__/CancerInvasionSteppables.cpython-312.pyc deleted file mode 100644 index 611fe30..0000000 Binary files a/Simulation/__pycache__/CancerInvasionSteppables.cpython-312.pyc and /dev/null differ