Skip to content

Commit ebecb7a

Browse files
canslab1claude
andcommitted
Pre-render README.md into index.html for SEO (static content for crawlers)
- Inject rendered README HTML between PRERENDER markers - Strip duplicate H1 (already in static HTML) - Crawlers now see full content instead of "Loading README..." - JS readme-loader.js detects pre-rendered content and applies syntax highlighting only Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 91b26db commit ebecb7a

1 file changed

Lines changed: 350 additions & 1 deletion

File tree

index.html

Lines changed: 350 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,356 @@
132132
<main class="content-wrapper">
133133
<article class="markdown-body" id="content" aria-live="polite">
134134
<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 &times; 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 &times; 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 &rarr; Exposed &rarr; Infective &rarr; Recovered &rarr; Immune &rarr; 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 &times; 500 macro lattice and 100 &times; 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>&ge; 6.5</td>
181+
</tr>
182+
<tr>
183+
<td>NumPy</td>
184+
<td>&ge; 1.24</td>
185+
</tr>
186+
<tr>
187+
<td>Numba</td>
188+
<td>&ge; 0.60.0</td>
189+
</tr>
190+
<tr>
191+
<td>pyqtgraph</td>
192+
<td>&ge; 0.13</td>
193+
</tr>
194+
<tr>
195+
<td>openpyxl</td>
196+
<td>&ge; 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 &times; 500 lattice) with real-time color-coded agent states; click to navigate the Micro tab (100 &times; 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 &times; 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 &rarr; 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) &lt; 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., &amp; 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., &amp; 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., &amp; 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 -->
136485
</article>
137486
</main>
138487
<footer class="site-footer">

0 commit comments

Comments
 (0)