|
132 | 132 | <main class="content-wrapper"> |
133 | 133 | <article class="markdown-body" id="content" aria-live="polite"> |
134 | 134 | <h1>CASMIM — Cellular Automata with Social Mirror Identities Model</h1> |
135 | | - <div class="loading">Loading README...</div> |
| 135 | + <!-- PRERENDER-START --> |
| 136 | +<p><img alt="Python 3.10+" src="https://img.shields.io/badge/Python-3.10%2B-blue"> |
| 137 | +<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-green"> |
| 138 | +<a href="https://canslab1.github.io/"><img alt="CANS Lab" src="https://img.shields.io/badge/CANS_Lab-Homepage-orange"></a></p> |
| 139 | +<p>A Python 3 implementation of the <strong>CASMIM</strong> model for simulating SARS transmission dynamics and evaluating public health policy interventions on a small-world epidemiological network.</p> |
| 140 | +<h2 id="overview">Overview</h2> |
| 141 | +<p>In the early 2000s, SARS outbreaks in cities such as Singapore, Taipei, and Toronto demonstrated how daily-contact social networks and long-distance movement could rapidly amplify disease spread. CASMIM addresses this by combining cellular automata with a "social mirror identity" mechanism: each person owns multiple <em>agents</em> (mirrors) scattered across a 500 × 500 torus lattice, representing the different social spheres (home, workplace, hospital, etc.) that a single individual participates in daily.</p> |
| 142 | +<p>The model integrates:</p> |
| 143 | +<ul> |
| 144 | +<li><strong>Cellular Automata</strong> on a 2D torus lattice (500 × 500) for spatial agent interactions</li> |
| 145 | +<li><strong>Social Mirror Identities</strong> to represent daily-contact social networks and long-distance movement</li> |
| 146 | +<li><strong>SEIR+D compartmental model</strong> (Susceptible → Exposed → Infective → Recovered → Immune → Susceptible, with Death branch)</li> |
| 147 | +<li><strong>8 public health policies</strong> (mask wearing, temperature screening, hospitalization, home quarantine, contact reduction, visit restriction, vaccination, medical policy)</li> |
| 148 | +<li><strong>Contact tracing</strong> via BFS-based algorithms with level-1 and level-2 quarantine</li> |
| 149 | +<li><strong>Super-spreader modeling</strong> and <strong>age-stratified mortality</strong></li> |
| 150 | +</ul> |
| 151 | +<p>The model was originally developed in Borland C++ Builder (2003-2005) and has been ported to Python 3 with a PySide6 (Qt) GUI.</p> |
| 152 | +<h2 id="features">Features</h2> |
| 153 | +<ul> |
| 154 | +<li><strong>Interactive lattice visualization</strong> — 500 × 500 macro lattice and 100 × 100 micro lattice with click-to-navigate</li> |
| 155 | +<li><strong>Real-time SEIR+D display</strong> — Color-coded agents (sky-blue = susceptible/exposed/immune, red = infective, silver = recovered, black = died)</li> |
| 156 | +<li><strong>6 chart types</strong> — Accumulation, incidence, notification, infection, accumulative quarantine, daily quarantine</li> |
| 157 | +<li><strong>8 configurable policies</strong> — Each policy can be toggled on/off during simulation with adjustable effect and coverage rates</li> |
| 158 | +<li><strong>Dynamic policy activation</strong> — Policies can be enabled or disabled mid-simulation to study intervention timing</li> |
| 159 | +<li><strong>Super-spreader modeling</strong> — Configurable probability for super-spreader designation</li> |
| 160 | +<li><strong>Excel output</strong> — Simulation statistics exported via openpyxl with 4 output sheets (cumulative counts, daily deltas, action log, running averages)</li> |
| 161 | +<li><strong>Numba JIT acceleration</strong> — Core simulation loop compiled to native code via Numba <code>@njit</code>, achieving ~8x speedup over pure Python; fallback to Python path via <code>CASMIM_NO_NUMBA=1</code></li> |
| 162 | +<li><strong>NumPy-accelerated</strong> — Structure-of-Arrays (SoA) data layout with vectorized operations for population-level computations</li> |
| 163 | +</ul> |
| 164 | +<h2 id="installation">Installation</h2> |
| 165 | +<pre><code class="language-bash">git clone https://github.com/canslab1/CASMIM.git |
| 166 | +cd CASMIM |
| 167 | +pip install -r requirements.txt |
| 168 | +</code></pre> |
| 169 | +<h3 id="dependencies">Dependencies</h3> |
| 170 | +<table> |
| 171 | +<thead> |
| 172 | +<tr> |
| 173 | +<th>Package</th> |
| 174 | +<th>Version</th> |
| 175 | +</tr> |
| 176 | +</thead> |
| 177 | +<tbody> |
| 178 | +<tr> |
| 179 | +<td>PySide6</td> |
| 180 | +<td>≥ 6.5</td> |
| 181 | +</tr> |
| 182 | +<tr> |
| 183 | +<td>NumPy</td> |
| 184 | +<td>≥ 1.24</td> |
| 185 | +</tr> |
| 186 | +<tr> |
| 187 | +<td>Numba</td> |
| 188 | +<td>≥ 0.60.0</td> |
| 189 | +</tr> |
| 190 | +<tr> |
| 191 | +<td>pyqtgraph</td> |
| 192 | +<td>≥ 0.13</td> |
| 193 | +</tr> |
| 194 | +<tr> |
| 195 | +<td>openpyxl</td> |
| 196 | +<td>≥ 3.1</td> |
| 197 | +</tr> |
| 198 | +</tbody> |
| 199 | +</table> |
| 200 | +<h2 id="usage">Usage</h2> |
| 201 | +<pre><code class="language-bash">python main.py |
| 202 | +</code></pre> |
| 203 | +<p>This launches the GUI application with:</p> |
| 204 | +<ul> |
| 205 | +<li><strong>Left panel</strong>: Disease parameters (Disease tab), population parameters (World tab), policy controls (Policy tab) with checkboxes and effect/coverage sliders</li> |
| 206 | +<li><strong>Center panel</strong>: Macro tab (500 × 500 lattice) with real-time color-coded agent states; click to navigate the Micro tab (100 × 100 magnified view)</li> |
| 207 | +<li><strong>Right panel</strong>: 6 pyqtgraph chart widgets displaying accumulation, incidence, notification, infection, and quarantine statistics</li> |
| 208 | +<li><strong>Bottom panel</strong>: 9-panel status bar showing coordinates, agent state, identity, current day, and mortality summary</li> |
| 209 | +</ul> |
| 210 | +<h3 id="controls">Controls</h3> |
| 211 | +<table> |
| 212 | +<thead> |
| 213 | +<tr> |
| 214 | +<th>Control</th> |
| 215 | +<th>Function</th> |
| 216 | +</tr> |
| 217 | +</thead> |
| 218 | +<tbody> |
| 219 | +<tr> |
| 220 | +<td><strong>Stop</strong></td> |
| 221 | +<td>Pause the simulation</td> |
| 222 | +</tr> |
| 223 | +<tr> |
| 224 | +<td><strong>Go</strong></td> |
| 225 | +<td>Execute continuous simulation (one day per step)</td> |
| 226 | +</tr> |
| 227 | +<tr> |
| 228 | +<td><strong>Setup</strong></td> |
| 229 | +<td>Initialize (or re-initialize) the population and lattice</td> |
| 230 | +</tr> |
| 231 | +<tr> |
| 232 | +<td><strong>Policy checkboxes</strong></td> |
| 233 | +<td>Toggle individual policies on/off during simulation</td> |
| 234 | +</tr> |
| 235 | +<tr> |
| 236 | +<td><strong>Vaccine button</strong></td> |
| 237 | +<td>Administer a batch of vaccines to random unvaccinated individuals</td> |
| 238 | +</tr> |
| 239 | +</tbody> |
| 240 | +</table> |
| 241 | +<h3 id="environment-variables">Environment Variables</h3> |
| 242 | +<table> |
| 243 | +<thead> |
| 244 | +<tr> |
| 245 | +<th>Variable</th> |
| 246 | +<th>Description</th> |
| 247 | +</tr> |
| 248 | +</thead> |
| 249 | +<tbody> |
| 250 | +<tr> |
| 251 | +<td><code>CASMIM_NO_NUMBA=1</code></td> |
| 252 | +<td>Disable Numba JIT and use the pure Python engine (useful for debugging or when Numba is unavailable)</td> |
| 253 | +</tr> |
| 254 | +</tbody> |
| 255 | +</table> |
| 256 | +<h2 id="disease-parameters">Disease Parameters</h2> |
| 257 | +<table> |
| 258 | +<thead> |
| 259 | +<tr> |
| 260 | +<th>Parameter</th> |
| 261 | +<th>Default</th> |
| 262 | +<th>Description</th> |
| 263 | +</tr> |
| 264 | +</thead> |
| 265 | +<tbody> |
| 266 | +<tr> |
| 267 | +<td><code>exposed_period</code></td> |
| 268 | +<td>5</td> |
| 269 | +<td>Average incubation period (days)</td> |
| 270 | +</tr> |
| 271 | +<tr> |
| 272 | +<td><code>symptomatic_period</code></td> |
| 273 | +<td>23</td> |
| 274 | +<td>Average symptomatic duration (days)</td> |
| 275 | +</tr> |
| 276 | +<tr> |
| 277 | +<td><code>infective_period</code></td> |
| 278 | +<td>3</td> |
| 279 | +<td>Average infectious period (days)</td> |
| 280 | +</tr> |
| 281 | +<tr> |
| 282 | +<td><code>recovered_period</code></td> |
| 283 | +<td>7</td> |
| 284 | +<td>Average recovery period (days)</td> |
| 285 | +</tr> |
| 286 | +<tr> |
| 287 | +<td><code>immune_period</code></td> |
| 288 | +<td>60</td> |
| 289 | +<td>Average immunity duration (days)</td> |
| 290 | +</tr> |
| 291 | +<tr> |
| 292 | +<td><code>quarantine_period</code></td> |
| 293 | +<td>10</td> |
| 294 | +<td>Quarantine/isolation duration (days)</td> |
| 295 | +</tr> |
| 296 | +<tr> |
| 297 | +<td><code>transmission_prob</code></td> |
| 298 | +<td>0.05</td> |
| 299 | +<td>Per-contact infection probability</td> |
| 300 | +</tr> |
| 301 | +<tr> |
| 302 | +<td><code>immune_prob</code></td> |
| 303 | +<td>0.02</td> |
| 304 | +<td>Natural immunity probability</td> |
| 305 | +</tr> |
| 306 | +<tr> |
| 307 | +<td><code>detect_rate</code></td> |
| 308 | +<td>0.9</td> |
| 309 | +<td>Symptom detection rate</td> |
| 310 | +</tr> |
| 311 | +<tr> |
| 312 | +<td><code>super_rate</code></td> |
| 313 | +<td>0.0001</td> |
| 314 | +<td>Super-spreader designation probability</td> |
| 315 | +</tr> |
| 316 | +<tr> |
| 317 | +<td><code>mortality_old</code></td> |
| 318 | +<td>0.52</td> |
| 319 | +<td>Mortality rate for elderly</td> |
| 320 | +</tr> |
| 321 | +<tr> |
| 322 | +<td><code>mortality_prime</code></td> |
| 323 | +<td>0.17</td> |
| 324 | +<td>Mortality rate for prime-age adults</td> |
| 325 | +</tr> |
| 326 | +<tr> |
| 327 | +<td><code>mortality_young</code></td> |
| 328 | +<td>0.05</td> |
| 329 | +<td>Mortality rate for young individuals</td> |
| 330 | +</tr> |
| 331 | +</tbody> |
| 332 | +</table> |
| 333 | +<h2 id="policy-parameters">Policy Parameters</h2> |
| 334 | +<table> |
| 335 | +<thead> |
| 336 | +<tr> |
| 337 | +<th>Policy</th> |
| 338 | +<th>Effect</th> |
| 339 | +<th>Coverage</th> |
| 340 | +<th>Description</th> |
| 341 | +</tr> |
| 342 | +</thead> |
| 343 | +<tbody> |
| 344 | +<tr> |
| 345 | +<td>Mask wearing</td> |
| 346 | +<td>0.9</td> |
| 347 | +<td>0.9</td> |
| 348 | +<td>Reduces transmission probability</td> |
| 349 | +</tr> |
| 350 | +<tr> |
| 351 | +<td>Temperature screening</td> |
| 352 | +<td>0.9</td> |
| 353 | +<td>0.9</td> |
| 354 | +<td>Increases detection rate for early isolation</td> |
| 355 | +</tr> |
| 356 | +<tr> |
| 357 | +<td>Hospital isolation</td> |
| 358 | +<td>0.5</td> |
| 359 | +<td>0.95</td> |
| 360 | +<td>Isolates infective individuals in hospital</td> |
| 361 | +</tr> |
| 362 | +<tr> |
| 363 | +<td>Home quarantine</td> |
| 364 | +<td>—</td> |
| 365 | +<td>0.81</td> |
| 366 | +<td>Quarantines contacts at home</td> |
| 367 | +</tr> |
| 368 | +<tr> |
| 369 | +<td>Visit restriction</td> |
| 370 | +<td>—</td> |
| 371 | +<td>0.9</td> |
| 372 | +<td>Restricts hospital visitors to reduce nosocomial infection</td> |
| 373 | +</tr> |
| 374 | +<tr> |
| 375 | +<td>Contact reduction</td> |
| 376 | +<td>—</td> |
| 377 | +<td>0.9</td> |
| 378 | +<td>Reduces social contacts (e.g., school/workplace closure)</td> |
| 379 | +</tr> |
| 380 | +<tr> |
| 381 | +<td>Vaccination</td> |
| 382 | +<td>—</td> |
| 383 | +<td>count</td> |
| 384 | +<td>Administers vaccines to random unvaccinated individuals</td> |
| 385 | +</tr> |
| 386 | +<tr> |
| 387 | +<td>Medical policy</td> |
| 388 | +<td>0.9</td> |
| 389 | +<td>0.9</td> |
| 390 | +<td>Applies antiviral treatment to infective individuals</td> |
| 391 | +</tr> |
| 392 | +</tbody> |
| 393 | +</table> |
| 394 | +<h2 id="algorithm-overview">Algorithm Overview</h2> |
| 395 | +<p>CASMIM simulates epidemic dynamics through a daily step cycle:</p> |
| 396 | +<ol> |
| 397 | +<li> |
| 398 | +<p><strong>Population initialization</strong> — 100,000 individuals are created with age-stratified demographics (young/prime/old). Each person is assigned multiple "social mirror" agents distributed across the 500 × 500 torus lattice using a Gaussian quota distribution, representing their presence in different social spheres.</p> |
| 399 | +</li> |
| 400 | +<li> |
| 401 | +<p><strong>Daily traversal</strong> — Each day, all individuals are traversed in a randomly chosen direction (forward or reverse) to eliminate ordering bias. For each person, the engine executes:</p> |
| 402 | +</li> |
| 403 | +<li> |
| 404 | +<p><strong>State transition</strong> — The SEIR+D state machine advances:</p> |
| 405 | +</li> |
| 406 | +<li><strong>Susceptible</strong>: Agents interact with Moore-neighborhood neighbors; transmission occurs with probability <code>transmission_prob</code> (modified by mask and medical policies).</li> |
| 407 | +<li><strong>Exposed</strong>: Counter increments; transitions to Infective after <code>exposed_period</code> days.</li> |
| 408 | +<li><strong>Infective</strong>: May be detected (with probability <code>detect_rate</code>) and isolated/quarantined. Transmission to neighbors continues. After <code>infective_period</code> days, transitions to Recovered or Died (age-stratified mortality).</li> |
| 409 | +<li><strong>Recovered</strong>: After <code>recovered_period</code> days, transitions to Immune.</li> |
| 410 | +<li> |
| 411 | +<p><strong>Immune</strong>: After <code>immune_period</code> days, returns to Susceptible (unless permanently immunized by vaccine).</p> |
| 412 | +</li> |
| 413 | +<li> |
| 414 | +<p><strong>Contact tracing</strong> — When an infective individual is detected, BFS-based contact tracing identifies level-1 (direct contacts) and optionally level-2 (contacts of contacts) neighbors for home quarantine.</p> |
| 415 | +</li> |
| 416 | +<li> |
| 417 | +<p><strong>Super-spreader effect</strong> — Super-spreaders interact with all 8 Moore-neighborhood cells instead of a randomly selected single neighbor, dramatically increasing their transmission reach.</p> |
| 418 | +</li> |
| 419 | +</ol> |
| 420 | +<h2 id="implementation-notes">Implementation Notes</h2> |
| 421 | +<ul> |
| 422 | +<li><strong>Numba JIT compilation</strong>: The core simulation loop (<code>change_society</code>) and all subroutines (13 functions total) are compiled to native code via <code>@nb.njit(cache=True)</code>, yielding ~8x speedup. BFS contact tracing uses pre-allocated arrays with head/tail pointers instead of Python <code>deque</code>.</li> |
| 423 | +<li><strong>AoS → SoA conversion</strong>: The original C++ Array-of-Structures (<code>society.people[i].state</code>) is converted to Structure-of-Arrays (<code>people_state[i]</code>) using NumPy for cache-friendly vectorized operations.</li> |
| 424 | +<li><strong>Contact tracing</strong>: Changed from recursive DFS (C++) to iterative BFS (Python/Numba) to avoid stack overflow on large populations.</li> |
| 425 | +<li><strong>Policy vectorization</strong>: All policy applications (except vaccination) use <code>np.random.random(N) < available</code> for O(1) per-person Bernoulli trials instead of scalar loops.</li> |
| 426 | +<li><strong>Incremental rendering</strong>: A dirty-set mechanism (<code>dirty_pids</code>) tracks only agents whose state changed each day, avoiding full-lattice repaints.</li> |
| 427 | +<li><strong>Chart rendering</strong>: Migrated from VCL TChart (C++) to pyqtgraph (Python) for real-time chart updates.</li> |
| 428 | +</ul> |
| 429 | +<h2 id="project-structure">Project Structure</h2> |
| 430 | +<pre><code>CASMIM/ |
| 431 | +├── main.py # Entry point |
| 432 | +├── requirements.txt # Python dependencies |
| 433 | +├── pyproject.toml # Package metadata (PEP 621) |
| 434 | +├── CITATION.cff # Citation metadata |
| 435 | +├── CHANGELOG.md # Version history |
| 436 | +├── CONTRIBUTING.md # Contribution guidelines |
| 437 | +├── LICENSE # MIT License |
| 438 | +├── index.html # GitHub Pages landing page |
| 439 | +├── 404.html # Custom 404 error page |
| 440 | +├── sitemap.xml # XML sitemap for search engines |
| 441 | +├── robots.txt # Crawler directives |
| 442 | +├── llms.txt # AI-readable project summary |
| 443 | +└── sars_sim/ |
| 444 | + ├── __init__.py |
| 445 | + ├── models.py # Data structures (StateEnum, SimulationParams, SimulationData) |
| 446 | + ├── world.py # Lattice management, population initialization, agent distribution |
| 447 | + ├── engine.py # Core SEIR+D simulation engine, transmission and state transition logic |
| 448 | + ├── engine_numba.py # Numba JIT-compiled kernels (13 @njit functions, ~8x speedup) |
| 449 | + ├── policies.py # 8 public health policy implementations (vectorized) |
| 450 | + ├── statistics.py # Statistics tracking, Excel output (4 sheets) |
| 451 | + └── gui/ |
| 452 | + ├── __init__.py |
| 453 | + ├── main_window.py # Main application window (PySide6) |
| 454 | + ├── lattice_view.py # Macro/micro lattice visualization (QImage ARGB32) |
| 455 | + ├── charts.py # 6 pyqtgraph chart widgets |
| 456 | + ├── controls.py # Parameter, disease, and policy control panels |
| 457 | + └── status_bar.py # 9-panel status bar |
| 458 | +</code></pre> |
| 459 | +<h2 id="authors">Authors</h2> |
| 460 | +<ul> |
| 461 | +<li><strong>Chung-Yuan Huang</strong> (黃崇源) — Department of Computer Science and Information Engineering, Chang Gung University, Taiwan (gscott@mail.cgu.edu.tw)</li> |
| 462 | +<li><strong>Chuen-Tsai Sun</strong> — Department of Computer Science, National Yang Ming Chiao Tung University, Taiwan</li> |
| 463 | +<li><strong>Ji-Lung Hsieh</strong> — Graduate Institute of Journalism, National Taiwan University, Taiwan</li> |
| 464 | +<li><strong>Yi-Ming Arthur Chen</strong> — Department of Information Management, National Central University, Taiwan</li> |
| 465 | +<li><strong>Holin Lin</strong> — Department of Sociology, National Taiwan University, Taiwan</li> |
| 466 | +</ul> |
| 467 | +<h2 id="citation">Citation</h2> |
| 468 | +<p>If you use this software in your research, please cite:</p> |
| 469 | +<blockquote> |
| 470 | +<p>Huang, C.-Y., Sun, C.-T., Hsieh, J.-L., Chen, Y.-M. A., & Lin, H. (2005). A Novel Small-World Model: Using Social Mirror Identities for Epidemic Simulations. <em>SIMULATION</em>, 81(10), 671-699. https://doi.org/10.1177/0037549705061519</p> |
| 471 | +</blockquote> |
| 472 | +<p>See <code>CITATION.cff</code> for machine-readable citation metadata.</p> |
| 473 | +<h2 id="references">References</h2> |
| 474 | +<ol> |
| 475 | +<li> |
| 476 | +<p>Huang, C.-Y., Sun, C.-T., Hsieh, J.-L., & Lin, H. (2004). Simulating SARS: Small-World Epidemiological Modeling and Public Health Policy Assessments. <em>Journal of Artificial Societies and Social Simulation</em>, 7(4), 2. http://jasss.soc.surrey.ac.uk/7/4/2.html</p> |
| 477 | +</li> |
| 478 | +<li> |
| 479 | +<p>Huang, C.-Y., Sun, C.-T., Hsieh, J.-L., Chen, Y.-M. A., & Lin, H. (2005). A Novel Small-World Model: Using Social Mirror Identities for Epidemic Simulations. <em>SIMULATION</em>, 81(10), 671-699. https://doi.org/10.1177/0037549705061519</p> |
| 480 | +</li> |
| 481 | +</ol> |
| 482 | +<h2 id="license">License</h2> |
| 483 | +<p>This project is licensed under the MIT License. See <a href="LICENSE">LICENSE</a> for details.</p> |
| 484 | +<!-- PRERENDER-END --> |
136 | 485 | </article> |
137 | 486 | </main> |
138 | 487 | <footer class="site-footer"> |
|
0 commit comments