<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Evgeny Metelkin</title>
    <description>The latest articles on DEV Community by Evgeny Metelkin (@metelkin).</description>
    <link>https://dev.to/metelkin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F47728%2Fe25133fc-b70a-42fd-b567-13ab7385cdfa.png</url>
      <title>DEV Community: Evgeny Metelkin</title>
      <link>https://dev.to/metelkin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/metelkin"/>
    <language>en</language>
    <item>
      <title>Keep R Awake During Long Jobs with NoSleepR</title>
      <dc:creator>Evgeny Metelkin</dc:creator>
      <pubDate>Fri, 28 Nov 2025 07:00:00 +0000</pubDate>
      <link>https://dev.to/metelkin/keep-r-awake-during-long-jobs-with-nosleepr-21jj</link>
      <guid>https://dev.to/metelkin/keep-r-awake-during-long-jobs-with-nosleepr-21jj</guid>
      <description>&lt;p&gt;When R runs something heavy for an hour or two, laptops don't always care - many will still go to sleep if there's no user activity.&lt;br&gt;&lt;br&gt;
On Windows with Modern Standby, on macOS with default power settings, or on Linux with aggressive power-saving policies, this can interrupt work even if R is still busy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NoSleepR&lt;/strong&gt; solves this problem with a simple idea:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;keep the system awake only while R is doing something important, and let it return to normal afterward.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It uses the operating system's official sleep-prevention mechanisms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; PowerRequest API
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS:&lt;/strong&gt; &lt;code&gt;caffeinate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux (systemd):&lt;/strong&gt; &lt;code&gt;systemd-inhibit&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No hacks, no fake mouse movement, and no permanent power-plan changes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Basic usage
&lt;/h2&gt;

&lt;p&gt;Install from CRAN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;install.packages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"NoSleepR"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;library&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NoSleepR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Turn sleep prevention on manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;nosleep_on&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;# long-running R work here&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;nosleep_off&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or wrap a block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;with_nosleep&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c1"&gt;# heavy computation here&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If needed, keep the screen awake too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;with_nosleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keep_display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c1"&gt;# long-running code&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful on Windows laptops that ignore sleep-prevention when the display turns off in battery mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this package exists
&lt;/h2&gt;

&lt;p&gt;Disabling sleep mode globally works, but it's overkill:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;consumes battery even when idle,&lt;/li&gt;
&lt;li&gt;requires changing system settings (sometimes blocked by admins),&lt;/li&gt;
&lt;li&gt;easy to forget to revert.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;NoSleepR&lt;/code&gt; keeps things simple: &lt;strong&gt;only stay awake when the code runs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your workflow calls &lt;strong&gt;C++&lt;/strong&gt;, &lt;strong&gt;Rcpp&lt;/strong&gt;, &lt;strong&gt;external binaries&lt;/strong&gt;, or other &lt;strong&gt;blocking system calls&lt;/strong&gt;, they are covered as long as R waits for them to finish.&lt;/p&gt;

&lt;h2&gt;
  
  
  What NoSleepR does ΝΟΤ do
&lt;/h2&gt;

&lt;p&gt;Some behaviors are controlled strictly by the OS and cannot be overridden:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;closing the laptop lid forces sleep,&lt;/li&gt;
&lt;li&gt;pressing the power button forces sleep,&lt;/li&gt;
&lt;li&gt;corporate-managed policies may override PowerRequest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On remote servers, the package does nothing: servers normally do not sleep, and remote session drops are usually network timeouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical scenarios
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;overnight simulations&lt;/li&gt;
&lt;li&gt;bootstrap or MCMC workflows&lt;/li&gt;
&lt;li&gt;machine-learning training loops&lt;/li&gt;
&lt;li&gt;ETL or data-cleaning pipelines&lt;/li&gt;
&lt;li&gt;unattended scripts on laptops with aggressive sleep policies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the "YouTube tab" method works for you, &lt;code&gt;NoSleepR&lt;/code&gt; will work too but without wasting power or being ridiculous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback
&lt;/h2&gt;

&lt;p&gt;Bug reports, suggestions, and contributions are welcome:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/hetalang/NoSleepR" rel="noopener noreferrer"&gt;https://github.com/hetalang/NoSleepR&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rstats</category>
      <category>datascience</category>
      <category>machinelearning</category>
      <category>modeling</category>
    </item>
    <item>
      <title>Keep Julia Awake: NoSleep.jl</title>
      <dc:creator>Evgeny Metelkin</dc:creator>
      <pubDate>Sat, 04 Oct 2025 07:00:00 +0000</pubDate>
      <link>https://dev.to/metelkin/keep-julia-awake-nosleepjl-4pko</link>
      <guid>https://dev.to/metelkin/keep-julia-awake-nosleepjl-4pko</guid>
      <description>&lt;p&gt;When you run long Julia simulations or heavy computations on a laptop, you don't want your machine to fall asleep in the middle of the job.&lt;br&gt;&lt;br&gt;
On Windows, macOS, or Linux, the system may suspend itself even if Julia is still crunching numbers — leading to wasted time, broken HTTP calls, or stalled jobs.  &lt;/p&gt;

&lt;p&gt;This is the reason &lt;a href="https://github.com/hetalang/NoSleep.jl" rel="noopener noreferrer"&gt;NoSleep.jl&lt;/a&gt; exists: a lightweight cross-platform Julia package that prevents your machine from falling asleep during long computations.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; uses WinAPI &lt;code&gt;SetThreadExecutionState&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS:&lt;/strong&gt; uses the built-in &lt;code&gt;caffeinate&lt;/code&gt; tool.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux (systemd):&lt;/strong&gt; uses &lt;code&gt;systemd-inhibit&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each backend is safe: once your block finishes (or Julia exits), the inhibitor is released automatically.&lt;/p&gt;
&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Block form&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;NoSleep&lt;/span&gt;

&lt;span class="n"&gt;with_nosleep&lt;/span&gt;&lt;span class="x"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Your long computation&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Keep the display awake too&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;with_nosleep&lt;/span&gt;&lt;span class="x"&gt;(;&lt;/span&gt; &lt;span class="n"&gt;keep_display&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Your long computation&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notes &amp;amp; Side-effects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Saves you from wasted hours if the OS suspends mid-job. No frustration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Useful when running code overnight or unattended.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cross-platform: works out of the box on Windows, macOS, and Linux.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does not prevent suspend/hibernate when you close the lid or press the laptop's power button — it only blocks automatic idle sleep.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Feedback and contributions welcome: &lt;a href="https://github.com/hetalang/NoSleep.jl" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>julia</category>
      <category>datascience</category>
      <category>machinelearning</category>
      <category>modeling</category>
    </item>
    <item>
      <title>Model Formats in Systems Pharmacology. Part 2: Engineering Practices We Can Borrow</title>
      <dc:creator>Evgeny Metelkin</dc:creator>
      <pubDate>Sat, 06 Sep 2025 20:12:00 +0000</pubDate>
      <link>https://dev.to/metelkin/model-formats-in-systems-pharmacology-part-2-engineering-practices-we-can-borrow-4fe4</link>
      <guid>https://dev.to/metelkin/model-formats-in-systems-pharmacology-part-2-engineering-practices-we-can-borrow-4fe4</guid>
      <description>&lt;p&gt;&lt;em&gt;In &lt;a href="https://dev.to/metelkin/model-formats-in-systems-pharmacology-part-1-the-missing-link-between-biology-and-software-33h1"&gt;Part 1&lt;/a&gt;, we looked at the landscape of QSP model formats-their origins, strengths, and limitations. In this follow-up, I want to step back and explore the problem from a software engineering perspective: what practices and design principles could make QSP modeling more transparent, modular, and reproducible, and how model formats can evolve to support that shift.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Model as code
&lt;/h2&gt;

&lt;p&gt;In software, the "X as code" idea has proven itself many times over: &lt;strong&gt;Infrastructure as Code&lt;/strong&gt; (&lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/infrastructure-as-code" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt;), &lt;strong&gt;Configuration as Code&lt;/strong&gt; (&lt;a href="https://www.redhat.com/en/blog/ansible-automation-platform-2.3-configuration-as-code-improvements" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt;), and &lt;strong&gt;Pipeline as Code&lt;/strong&gt; (&lt;a href="https://www.jenkins.io/doc/book/pipeline/jenkinsfile/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;), among others. The core idea is simple: we don't just manage &lt;strong&gt;artifacts&lt;/strong&gt; (infrastructure, configuration, pipelines) directly, we manage their &lt;strong&gt;textual representation&lt;/strong&gt; under version control, even if those artifacts were never treated as "code" before. In all cases, the &lt;strong&gt;authoritative source&lt;/strong&gt; (canonical source for other forms) is human-readable text. This doesn't exclude working with diagrams or tables-authoring can stay visual or interactive, but the canonical format must still be code. This shift brought massive gains in transparency, modularity, and reproducibility, and accelerated progress in software engineering.&lt;/p&gt;

&lt;p&gt;If we look back at the popular formats discussed earlier, not all of them can be considered model as code. Some are well-suited; others are not. QSP formats that are stored in binary or tool-specific project files cannot be treated as code. Formats that are formally "text-based" but too complex or unstructured for a human to read or write also only partially fit this concept.&lt;/p&gt;

&lt;p&gt;When this principle is in place, modelers gain access to an entire ecosystem of tools: version control, diff and merge utilities, code completion, automated testing, and CI/CD pipelines. Nothing needs to be reinvented-these are the same practices that software engineers already use. It means versioned, testable, modular, and reusable models.&lt;/p&gt;

&lt;p&gt;In practice, a model becomes more than a loose collection of files: it turns into a full engineering project with a clear folder structure, documentation, and automation. This approach improves reproducibility, makes validation and review more systematic, and simplifies onboarding new team members.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Transparency
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Code transparency&lt;/strong&gt; means that every aspect of a model is visible, reviewable, and understandable &lt;strong&gt;at a glance&lt;/strong&gt;. This covers not only the model structure, but also the equations, parameters, and the assumptions embedded within it. A transparent format allows collaborators to see what exactly the model does without needing the original author or a proprietary tool to "explain" it.&lt;/p&gt;

&lt;p&gt;A second requirement is &lt;strong&gt;traceable change&lt;/strong&gt;. This is not only about being able to read the code, but also about being able to see what changed and why between versions. With text-based formats, differences are captured by standard tools (e.g., Git diff), making version control, peer review, and collaboration far more effective.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwhaa80n2ghidoxtsgeb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwhaa80n2ghidoxtsgeb.png" alt="Traceable change for NONMEM file" width="800" height="470"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Fig. 1. Traceable change for NONMEM model file.&lt;/strong&gt; Files comparison in VSCode: old vs. new. Can see changes clearly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A desirable (not strictly mandatory) requirement is &lt;strong&gt;self-explanatory code&lt;/strong&gt;. This means that the model description carries enough context-through clear naming, annotations, and units-that a new reader can understand the intent without constantly referring back to external notes or publications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgsxd1xolnuxk9e38uj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgsxd1xolnuxk9e38uj0.png" alt="Self-explanatory code trace in Antimony modeling language" width="800" height="382"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Fig. 2. Self-explanatory code trace in Antimony modeling language.&lt;/strong&gt; File comparison in VSCode: old vs. new. Model diff meaning easy to understand at a glance because of clear syntax.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By contrast, QSP environments that store models in binary, closed, or otherwise non-readable formats cannot ensure transparency. They block the very practices-review, versioning, collaboration-that modern scientific software relies on. Even when dedicated comparison tools exist, they are typically ad-hoc, tied to a single platform, and rarely integrate smoothly into a team's normal project workflow. As a result, they are used sporadically and do not replace true text-level transparency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61n153vgsjwkqrq7vpiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61n153vgsjwkqrq7vpiz.png" alt="Non traceable change for SimBiology project" width="800" height="429"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Fig. 3. Non traceable change for SimBiology project (.sbproj).&lt;/strong&gt; File comparison in VSCode: old vs. new. Model change cannot be tracked because of binary format.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Modularity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Modularity&lt;/strong&gt; is the ability to divide a project into independent parts that can be developed, tested, and reused separately. It comes from having clear interfaces and well-defined dependencies between components.&lt;/p&gt;

&lt;p&gt;Here we use the term broadly. It includes both the &lt;strong&gt;separation of different project layers&lt;/strong&gt;: model, data, scripts (covered in more detail in the "Separation of Concerns" section), and the internal modularization of the model itself into subcomponents that are easier to manage and understand.&lt;/p&gt;

&lt;p&gt;What modularity brings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code reuse.&lt;/strong&gt; Modules can be packaged and reused across projects or systems, avoiding copy-paste and enabling larger blocks to become shared dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clarity and maintainability.&lt;/strong&gt; Smaller, self-contained pieces are easier to read, document, and hand over to new collaborators.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability.&lt;/strong&gt; Adding a new drug, pathway, or dataset means extending the project with a module rather than rewriting existing code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experimentation and flexibility.&lt;/strong&gt; Alternative implementations (e.g., two different PK models) can be swapped or compared without touching the rest of the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more logically a QSP platform is divided into modules, the easier it becomes to manage the work and distribute responsibilities. A single monolithic file forces the entire team to work sequentially, rather than in parallel.&lt;/p&gt;
&lt;h3&gt;
  
  
  Longevity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Longevity&lt;/strong&gt; means that a model remains usable and trustworthy years after it was first created. Instead of "remembering which buttons we clicked," the project can be rebuilt, rerun, and revalidated from its source (&lt;a href="http://dx.doi.org/10.1038/sdata.2016.18" rel="noopener noreferrer"&gt;FAIR Principles, Scientific Data, 2016&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr10hwm6mv7elogo4kn93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr10hwm6mv7elogo4kn93.png" alt="Git commit history in QSP project." width="800" height="331"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Fig. 4. Git commit history in QSP project.&lt;/strong&gt;: Commit history provides a timeline of changes in branches, enabling easy rollback and review.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What makes longevity possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version history.&lt;/strong&gt; With Git or similar systems, projects can be saved as a sequence of working snapshots. Each commit captures the state of parameters, equations, and scenarios at a given moment, creating a project timeline that can be revisited or rolled back when needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment capture.&lt;/strong&gt; Pinned dependencies and solver settings (e.g., Project.toml, requirements.txt, renv.lock) ensure the same model can be executed in the future, regardless of local updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readable formats.&lt;/strong&gt; Text-based models outlive specific tools; even if a GUI disappears, the core code can still be read, parsed, and converted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-validation.&lt;/strong&gt; As new data or regulatory requirements arise, archived models can be rerun and checked against updated knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge preservation.&lt;/strong&gt; Annotations, comments, and documentation carry context, so understanding does not depend on the original author's memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulatory and audit needs.&lt;/strong&gt; Long-term reproducibility is critical for submissions: teams must show exactly what model was used to support a decision at a given time (&lt;a href="//http:/dx.doi.org/10.1002/psp4.12049"&gt;MID3 Good Practices, CPT: PSP, 2016&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Longevity turns a QSP model from a one-off experiment into a &lt;strong&gt;sustainable scientific asset&lt;/strong&gt;, something that can be reliably shared, revisited, and built upon.&lt;/p&gt;
&lt;h3&gt;
  
  
  Automation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Automation&lt;/strong&gt; means that models are executed and tested through scripts instead of manual clicks. Once a model is code, it can be integrated into pipelines that ensure consistent, repeatable runs for testing, simulations, parameter estimation, or sensitivity analyses.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;CI/CD&lt;/strong&gt;, every commit can automatically launch validation tasks, generate reports, or even dispatch heavy computations to a more powerful server or cluster (&lt;a href="https://www.oreilly.com/library/view/continuous-delivery-reliable/9780321670250/" rel="noopener noreferrer"&gt;Continuous Delivery, Addison-Wesley, 2010&lt;/a&gt;). This reduces human error, scales effortlessly, and makes QSP projects more reliable and collaborative .&lt;/p&gt;
&lt;h3&gt;
  
  
  LLM &amp;amp; AI
&lt;/h3&gt;

&lt;p&gt;When models are stored as readable code, they become accessible not only to people but also to &lt;strong&gt;AI assistants&lt;/strong&gt;. This opens new opportunities for collaboration between modelers and &lt;strong&gt;Large Language Models&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwoa9p4ldcl9tzruw63o0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwoa9p4ldcl9tzruw63o0.png" alt="Autocompletion by GitHub Copilot for Heta" width="800" height="503"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Fig.5. Autocompletion for Heta code.&lt;/strong&gt; GitHub Copilot can assist with code suggestions and completions if the model has unified and clear structure. Red arrow points to the AI generated suggestion.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Assisted modeling.&lt;/strong&gt; Existing tools like GitHub Copilot or Cursor can already be used with QSP models stored as code-offering chat-based assistance, code generation, or autocompletion in Domain-Specific Language (DSL)/Macros/JSON, just as they do today for Python or R scripts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Report integration.&lt;/strong&gt; Because the model is code, the model updates and results can be automatically pulled into human-readable reports, presentations, or dashboards. LLMs can help generate narratives that explain changes, assumptions, or results based on the current model state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model as knowledge base.&lt;/strong&gt; A structured repository can serve as a living knowledge base for LLMs. By indexing models and metadata, teams can query them conversationally ("how is clearance modeled here?") or connect them with external literature for reasoning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated generation.&lt;/strong&gt; Beyond code completion, LLMs could be used to generate entire model fragments or even full models from structured descriptions, project specifications, or natural-language prompts. For example, a developer might design a tool that takes a pathway description or a clinical protocol and produces a ready-to-run QSP model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used carefully--with validation, tests, and human review--AI support can turn QSP models into more &lt;strong&gt;interactive, transparent, and productive assets&lt;/strong&gt;, while preserving scientific rigor.&lt;/p&gt;

&lt;p&gt;By contrast, if the model exists only as a binary project and the GUI is the only interface, none of these benefits are available: assistants cannot read or suggest code, generation and reporting are manual, and the project remains a &lt;strong&gt;closed box&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Separation of Concerns
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Separation of Concerns&lt;/strong&gt; is a principle borrowed from software engineering. Applied to QSP, it means treating each aspect of a project as its own &lt;strong&gt;layer with clear boundaries&lt;/strong&gt; and contracts. The model is not the data. The runtime is not the source. When these lines blur, projects become harder to read, validate, and reuse. When they are explicit, projects stay modular, and easier to evolve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layers (at a glance):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt; - description of system, biological processes: structure, equations, annotation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scenarios&lt;/strong&gt; - experiment conditions: dosing, schedules, observables, simulation horizons, parameter variations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data&lt;/strong&gt; - experimental/clinical datasets, raw or statistical data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tasks&lt;/strong&gt; - computational actions (simulate/fit/sensitivity/identifiability) referencing Model/Scenarios/Data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solver config &amp;amp; Environment&lt;/strong&gt; - numerical settings plus lockfiles/containers (library and OS versions).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime/Engines&lt;/strong&gt; - applications, solvers and interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipelines &amp;amp; Notebooks&lt;/strong&gt; - automation (CLI/CI/CD) and interactive analysis (Jupyter/Quarto).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Results/Reports&lt;/strong&gt; - outputs, logs, and report artifacts (generated by pipelines; not hand-edited).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs/Metadata&lt;/strong&gt; - general annotations, assumptions, references, ontologies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a fairly fine-grained breakdown for illustration. In real projects, separation can take different forms: dedicated folders, individual files, or clear structural sections inside one file in some cases. The key is that layers stay distinct, not mixed.&lt;/p&gt;

&lt;p&gt;Another point is that each layer carries &lt;strong&gt;its own logic and conventions&lt;/strong&gt;. A sensitivity-analysis script has very different requirements than a model structure. Automation may rely on technologies with its own style of configuration. Forcing everything into a monolithic structure only makes projects fragile.&lt;/p&gt;

&lt;p&gt;The idea is familiar from software engineering: web applications separate frontend, backend, and database; frameworks use MVC or MVVM patterns. QSP projects benefit from the same discipline: each layer does its job, connected by explicit interfaces rather than hidden assumptions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;A practical way to implement "Separation of Concerns" is through a &lt;strong&gt;clear and consistent project structure&lt;/strong&gt;. When each layer has its own dedicated place, the project becomes easier to navigate, test, and extend. In other words, the folder layout itself enforces modularity and discipline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qsp-project/
  model/          # core structure: states, reactions, equations
  data/           # measurements for calibration/validation
  scenarios/      # description of experimental conditions and parameters
  docs/           # General purpose annotations, assumptions for the whole project
  results/        # outputs, logs, reports (generated, not hand-edited)
  julia/          # Julia code for simulation and analysis
  R/              # R code for simulation and analysis
  project.yml     # machine-readable top-level metadata, dependencies, configuration
  README.txt      # human-readable overview and instructions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such a layout makes a QSP project behave like any other modern &lt;strong&gt;software repository&lt;/strong&gt;: modular, reviewable, and easy to share. The exact structure may vary depending on how well the project can be split into layers, which tools are in use, and the team's workflow. The key is not the specific folder names, but that the structure is &lt;strong&gt;consistent, agreed upon, and understood&lt;/strong&gt; by everyone on the team. This shared and long-term convention reduces friction, improves collaboration, and ensures that new members can quickly find their way around the project.&lt;/p&gt;

&lt;p&gt;These additional principles make project structures more robust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep the repository clean.&lt;/strong&gt; The project folder should only contain what is essential: model code, data, scenarios, tasks, configuration, and documentation. Avoid bundling software installers, outdated model versions, or random drafts and unused scripts. Such clutter makes navigation harder and undermines clarity. Version control (Git) and artifact registries are the right place for history and distributions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single source of truth.&lt;/strong&gt; Everything required to run or reproduce the project must either be part of the repository or referenced in a reliable, long-term way. No ambiguous dependencies on "files somewhere on a laptop" or "datasets hidden in a presentation." If a script was written for the project, it should live in the project. If external data cannot be included directly, it must be referenced with a stable identifier or DOI and clear provenance. This ensures reproducibility and integrity over time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stable naming and references.&lt;/strong&gt; Avoid renaming files, folders, or key identifiers without a strong reason. Frequent or unnecessary renames break links, confuse collaborators, and make version history harder to follow. Stable names act as anchors for scripts, pipelines, and external references, ensuring continuity and trust in the project's structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation as code.&lt;/strong&gt; Documentation should live alongside the project and evolve together with it. Assumptions, references, and instructions belong under version control, not in scattered slides or personal notes. Keeping docs close to the source makes them reviewable, traceable, and always in sync with the current state of the project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Model Layout
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why this matters.&lt;/strong&gt; Data scientists have long kept data in tabular, diff-friendly formats (CSV/TAB/Parquet) and code in versioned scripts (R/Julia/Matlab/Python). The persistent gap in QSP is the model layer: when a model has no canonical, human-readable source, you can't reliably diff or review changes, and you can't automate validation. Everything downstream-reproducibility, CI, and collaboration-degrades.&lt;/p&gt;

&lt;p&gt;"Model as code" principle treats the model as a &lt;strong&gt;declarative artifact&lt;/strong&gt; with its own lifecycle. The source of truth is text. GUIs, notebooks, and binaries are authoring or execution surfaces, not the canonical store. This simple rule unlocks code review, versioning, composition, and automation for the model layer exactly as it does for code and data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contracts: how layers talk.&lt;/strong&gt; When the model is kept separate from the rest of the project, it needs a clear way for other layers to reference it. Scenarios, tasks, and datasets should point to model elements through explicit identifiers-states, parameters, events, or observables in namespaces-rather than by position, file order, or ad-hoc labels. These references must be validated automatically, with pipelines configured to fail fast if an ID is missing or renamed. Stability here does not mean immobility, but transparent, predictable evolution. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modularity at the model level.&lt;/strong&gt; A practical layout, if your tools support a DSL or modular model files, might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model/
  core.dsl          # base states/params/eqs
  pk.dsl            # PK submodule (imports core)
  pd.dsl            # PD submodule
  cell-dynamics.dsl # cell dynamics submodule
  index.dsl         # top-level file that composes/exports modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When available, this approach has clear advantages: each file has a narrow, stable responsibility; imports and namespaces let you compose submodels cleanly; and a single &lt;strong&gt;index&lt;/strong&gt; provides the surface for downstream layers to import. This makes reuse straightforward, modules can be copied or version-pinned across repositories instead of duplicating whole projects. Even if your current environment doesn't provide such modularity, aiming for stable paths, explicit IDs, and a clear separation of responsibilities will bring similar benefits and reduce churn that breaks links or history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tooling for the model layer.&lt;/strong&gt; The model layer benefits from having its own basic checks, just like data or code. At minimum, tools should confirm that equations are dimensionally consistent, that all references point to something that exists, and that every state or parameter is defined only once. It helps to run quick "sanity" simulations on each update to confirm the model still produces reproducible results. These lightweight checks make errors visible early and keep the model trustworthy as it grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authoring &amp;amp; round-trip workflow.&lt;/strong&gt; You can build or edit a model wherever it's convenient, through a GUI, a notebook, or even a helper script. What matters is that the final result is always saved back into a clear, text-based format. That text is what goes under version control, what reviewers look at, and what other tools check for errors. This way modelers stay free to use familiar interfaces, while the project still keeps a consistent, transparent record.&lt;/p&gt;

&lt;h3&gt;
  
  
  Roles &amp;amp; Handoffs (who edits which layer)
&lt;/h3&gt;

&lt;p&gt;Different specialists can work productively when boundaries are explicit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model Engineer (biology focused).&lt;/strong&gt; Owns Model + Scenarios. Delivers: validated model modules, annotations, units.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Biostatistician / Data Manager (data analysis focused).&lt;/strong&gt; Owns Data and results. Delivers: cleaned datasets with units and provenance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simulation Engineer (computational methods focused).&lt;/strong&gt; Owns Tasks + Runtime + Solver config. Delivers: task specs, algorithms, tolerances, acceptance criteria.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime &amp;amp; DevOps Engineer (automation focused).&lt;/strong&gt; Owns Pipelines &amp;amp; Notebooks + Environment. Delivers: containers/lockfiles, solver configs, CI/CD configs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on the project's goals and team size, some roles may be combined, have other titles, or be unnecessary (for example, a dedicated DevOps engineer may not be required). In other cases, additional roles can emerge, such as a technical/medical writer, visualization scientist, or a platform architect/manager. These specialists may work full time, contribute periodically or only at specific stages, but in all cases, a well-structured layered project plus clear conventions makes the whole work more effective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anti-patterns
&lt;/h3&gt;

&lt;p&gt;In software engineering, &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/List_of_software_anti-patterns" rel="noopener noreferrer"&gt;anti-patterns&lt;/a&gt;&lt;/strong&gt; are recurring practices that may seem convenient but ultimately hinder maintainability, scalability, and collaboration. QSP projects face similar risks. Identifying such anti-patterns is important because it helps teams recognize fragile structures early, and avoid repeating common mistakes. Here is the examples of anti-patterns that often appear in QSP projects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Classic Anti-Pattern&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Manifestation in QSP projects&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Why it's harmful&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Big Ball of Mud&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Entire model, data, protocols, tasks, and results stored in a single monolithic file or notebook.&lt;/td&gt;
&lt;td&gt;No modularity, hard to review, impossible to scale or work in parallel.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Swiss Army Knife&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One application tries to do everything-modeling, simulation, analysis, data management, and reporting-without clear separation of roles.&lt;/td&gt;
&lt;td&gt;Lacks flexibility, becomes overly complex, and prevents use of specialized tools.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Copy-and-Paste Programming&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Equations and parameters duplicated or hard-coded into scripts and notebooks instead of being managed in a structured model source.&lt;/td&gt;
&lt;td&gt;Leads to inconsistencies, errors, and maintenance headaches.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Magic Numbers / Hidden Dependencies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Defaults for model structure, doses, solver tolerances, or units applied implicitly in GUIs, with no audit trail or explicit configuration.&lt;/td&gt;
&lt;td&gt;Non-transparent, hard to reproduce, fragile under review.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stovepipe System&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A model format or tool originally designed for smaller systems or narrow use cases, stretched to large-scale systems without modularity or namespaces.&lt;/td&gt;
&lt;td&gt;Doesn't scale, encourages hacks, and blocks extension or reuse.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inner-Platform Effect&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forcing all roles (modelers, data scientists, analysts) into a single rigid workflow, instead of allowing different business logics and affordances.&lt;/td&gt;
&lt;td&gt;Stifles productivity, mismatches workflows, and limits adaptability.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  7. Evaluating Your Workflow
&lt;/h2&gt;

&lt;p&gt;A couple of checklists is a simple way how you can check how well your current tools and workflows align with the principles of &lt;strong&gt;"model as code"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mark ☑ for each practice that is true for your current workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model-as-Code Maturity Checklist
&lt;/h3&gt;

&lt;p&gt;This test is not about scoring "perfect" compliance. Instead, it highlights areas where improvements may bring the biggest benefits, such as versioning, automation, or separation of layers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;☐ &lt;strong&gt;Text-based authoritative source.&lt;/strong&gt; Every part of the project can be expressed in a human-readable text format (DSL/Macros/JSON/YAML).&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Model layer separation.&lt;/strong&gt; The model is stored separately from data, code, and results. Model files contain only model structure, equations, parameters, and annotations.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Extensibility.&lt;/strong&gt; You can add new components, pathways, drugs, and scripts without rewriting existing code. The time you spend on this is proportional to the size of updates, not exponential.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Annotated &amp;amp; self-explanatory.&lt;/strong&gt; Your model includes clear names, units, and comments that explain its structure and assumptions. Annotations are machine-readable and will be preserved across tools.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Tool-agnostic.&lt;/strong&gt; You can open, edit and execute the model and other project parts using more or one tool. Or at least export/import to/from other formats without loss of information.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Meaningful diffs.&lt;/strong&gt; When a file changes, you can review and understand the difference (both technically and semantically) easily for any part of the project.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Scriptable execution.&lt;/strong&gt; You are able to run and repeat simulations, fits, tests, and analyses from the command line or scripts, not only through a GUI.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Reproducible environment.&lt;/strong&gt; Dependencies, solver versions, and configuration are pinned (e.g., lockfiles, containers).&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Clear structure.&lt;/strong&gt; The project follows a consistent folder/file layout that separates model, data, tasks, and results. All members of your project understand where to find and edit each part of the project.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Project conventions.&lt;/strong&gt; Your team has agreed on conventions for naming, versioning, and structuring the project. These conventions are documented and followed consistently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Modern Practices Checklist
&lt;/h3&gt;

&lt;p&gt;This checklist helps assess how much your project or workflow utilizes modern engineering practices.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;☐ &lt;strong&gt;Version control.&lt;/strong&gt; The project is under Version Control Tools (Git or equivalent), with meaningful commit history.
&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Continuous Integration &amp;amp; Delivery (CI/CD).&lt;/strong&gt; Substantial change triggers automated builds or checks (e.g., GitHub Actions, GitLab CI, Jenkins).
&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Automated reporting.&lt;/strong&gt; Reports, figures, and logs are generated directly from code and kept in sync with model versions.
&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Automated testing.&lt;/strong&gt; Unit or reproducibility tests verify correctness of model components and pipelines.&lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Automation of routine tasks.&lt;/strong&gt; Data preprocessing, parameter fitting are scripted, not manual. Routine operations can be autocompleted or assisted by AI tools. &lt;/li&gt;
&lt;li&gt;☐ &lt;strong&gt;Remote execution.&lt;/strong&gt; Workflows can seamlessly run on HPC clusters (like SLURM) or cloud resources when needed.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;A little "code" goes a long way: meaningful diffs, reproducibility, peer review, automated reports. The biology doesn't get lost—if anything, it's easier to separate scientific intent from routine clicks. You're still modeling, not coding for coding's sake; you just gain control and a verifiable history&lt;/em&gt;&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>modeling</category>
      <category>datascience</category>
      <category>pharma</category>
    </item>
    <item>
      <title>Model Formats in Systems Pharmacology. Part 1: The Missing Link Between Biology and Software Engineering</title>
      <dc:creator>Evgeny Metelkin</dc:creator>
      <pubDate>Fri, 22 Aug 2025 20:12:00 +0000</pubDate>
      <link>https://dev.to/metelkin/model-formats-in-systems-pharmacology-part-1-the-missing-link-between-biology-and-software-33h1</link>
      <guid>https://dev.to/metelkin/model-formats-in-systems-pharmacology-part-1-the-missing-link-between-biology-and-software-33h1</guid>
      <description>&lt;h2&gt;
  
  
  1. Intro
&lt;/h2&gt;

&lt;p&gt;Imagine web development where every framework has its own version of HTML, CSS, and JavaScript. &lt;strong&gt;Git is almost useless&lt;/strong&gt;: the project is a mix of binary files and settings hidden in a GUI. &lt;strong&gt;Code can't be reused&lt;/strong&gt;: each tool has its own syntax, its own logic, and a closed project file.&lt;/p&gt;

&lt;p&gt;Sounds like a bad alternate reality, but this is still how data storage and exchange often look in drug modeling. Tools solve similar problems, but &lt;strong&gt;model formats&lt;/strong&gt; are &lt;strong&gt;incompatible&lt;/strong&gt;; project structure is a "black box"; reproducibility is fragile; exchange is painful.&lt;/p&gt;

&lt;p&gt;In this article, we propose looking at a &lt;strong&gt;pharmacological model as code&lt;/strong&gt;, and at the model format as an interface between people and tools.&lt;/p&gt;

&lt;p&gt;We'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what &lt;strong&gt;QSP&lt;/strong&gt; is and the role modeling plays in &lt;strong&gt;pharmacology&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;what makes up a QSP model and how &lt;strong&gt;mathematics turns into structure&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;the main approaches to &lt;strong&gt;model description&lt;/strong&gt; (ODE scripts, process-based DSLs, tables, visual editors);&lt;/li&gt;
&lt;li&gt;how popular tools &lt;strong&gt;store projects&lt;/strong&gt; and where collaboration breaks down;&lt;/li&gt;
&lt;li&gt;which software &lt;strong&gt;engineering practices&lt;/strong&gt; (layered architecture, testing, CI/CD, semantic diffs) can actually work in QSP;&lt;/li&gt;
&lt;li&gt;how we can improve the situation with model formats in QSP.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Why QSP Matters
&lt;/h2&gt;

&lt;p&gt;Today, &lt;strong&gt;computational biology&lt;/strong&gt; and &lt;strong&gt;mathematical modeling&lt;/strong&gt; are essential in &lt;strong&gt;drug development&lt;/strong&gt; - from early &lt;strong&gt;preclinical experiments&lt;/strong&gt; in a test tube to full-scale &lt;strong&gt;clinical trials&lt;/strong&gt; in humans. Major pharmaceutical companies are investing heavily in this field, hiring top experts in computational biology to streamline the process and make it more effective (&lt;a href="https://doi.org/10.1007/s10928-024-09905-y" rel="noopener noreferrer"&gt;Industry Perspective, JPKPD, 2024&lt;/a&gt;; &lt;a href="https://doi.org/10.1124/jpet.123.001842" rel="noopener noreferrer"&gt;Promotional Submission of QSP, JPET, 2024&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;One of the fastest-growing areas is &lt;strong&gt;Quantitative Systems Pharmacology (QSP)&lt;/strong&gt;. In short, QSP builds detailed mathematical models that describe how &lt;strong&gt;drugs&lt;/strong&gt; interact with the human body and how biological systems respond in return (&lt;a href="https://customsitesmedia.usc.edu/wp-content/uploads/sites/106/2012/12/17062522/NIH-White-Papaer-2011.pdf" rel="noopener noreferrer"&gt;NIH QSP White Paper, 2011&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Think of the human body as a &lt;strong&gt;complex engineered system&lt;/strong&gt; - full of components, feedback loops, and regulators. QSP turns this system into math: models that allow pharmacologists, engineers, and statisticians to test drug behavior &lt;strong&gt;virtually&lt;/strong&gt; before moving to costly and risky experiments in the lab or clinic. Much like an aerospace engineer tests a new airplane in a simulator long before the first real flight.&lt;/p&gt;

&lt;h3&gt;
  
  
  How QSP Relates to Other Modeling Fields
&lt;/h3&gt;

&lt;p&gt;Long before QSP became a term, &lt;strong&gt;modelers&lt;/strong&gt; were already working with related approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Systems Biology (SB)&lt;/strong&gt; - models networks of &lt;strong&gt;molecules and cells&lt;/strong&gt; (typically non-related to drugs or clinical endpoints).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Physiologically Based Pharmacokinetics (PBPK)&lt;/strong&gt; - models how drugs move through &lt;strong&gt;organs and tissues&lt;/strong&gt;, and eliminates from the &lt;strong&gt;body&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pharmacokinetics/Pharmacodynamics (PK/PD)&lt;/strong&gt; - links drug concentration to its &lt;strong&gt;therapeutic effect&lt;/strong&gt;, typically &lt;strong&gt;empirically&lt;/strong&gt; or by compartmental approach.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;QSP didn't appear out of nowhere - it grew out of all three. But it raised the level of detail, scaled up from molecules to &lt;strong&gt;whole-body systems&lt;/strong&gt;, and aimed to bridge the gap between mechanism and clinic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Software Engineers Should Care
&lt;/h3&gt;

&lt;p&gt;From a developer's perspective, QSP projects look surprisingly familiar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there is &lt;strong&gt;code&lt;/strong&gt; (equations, parameters, model structure),&lt;/li&gt;
&lt;li&gt;there are &lt;strong&gt;tests&lt;/strong&gt; (validation against clinical or experimental data),&lt;/li&gt;
&lt;li&gt;there are &lt;strong&gt;versions&lt;/strong&gt; (models evolve as new data arrives),&lt;/li&gt;
&lt;li&gt;there are &lt;strong&gt;teams&lt;/strong&gt; working together on the same project,&lt;/li&gt;
&lt;li&gt;and there are real concerns about &lt;strong&gt;readability&lt;/strong&gt;, &lt;strong&gt;reproducibility&lt;/strong&gt;, and &lt;strong&gt;maintainability&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Drug modeling&lt;/strong&gt; is starting to resemble software engineering but without the benefit of decades of best practices. That's why ideas like &lt;strong&gt;modularity&lt;/strong&gt;, &lt;strong&gt;version control&lt;/strong&gt;, &lt;strong&gt;open formats&lt;/strong&gt;, and &lt;strong&gt;CI/CD&lt;/strong&gt; are so relevant here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current Challenges
&lt;/h3&gt;

&lt;p&gt;For all its promise, QSP is still far from smooth sailing. In practice, many QSP teams still run into systemic challenges.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Teamwork is hard.&lt;/strong&gt; Models are often locked inside proprietary tools, making collaboration feel more like passing around black boxes than working on shared code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interpretation is tricky.&lt;/strong&gt; Results can be meaningful to insiders, but remain opaque to biologists, clinicians, or decision-makers who actually need to use them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility is fragile.&lt;/strong&gt; The same model may give slightly different results depending on the tool, environment, or even the person running it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standards are missing.&lt;/strong&gt; Each group develops its own formats and workflows, so models don't travel well between teams or platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance is painful.&lt;/strong&gt; Every new dataset or scientific insight often means heavy, manual re-work of existing models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, QSP has the ambition of being an &lt;strong&gt;"engineering discipline for pharmacology"&lt;/strong&gt;, but today it still operates with the patchiness and friction of a young science.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Anatomy of QSP models
&lt;/h2&gt;

&lt;p&gt;In Quantitative Systems Pharmacology, the body is usually represented as a &lt;strong&gt;network of reactions&lt;/strong&gt; and interactions across scales—from organs to cells to molecules. Regardless of the level of detail, most models can be broken down into a few common building blocks. If we borrow concepts from software engineering, the parallels look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Modeling&lt;/th&gt;
&lt;th&gt;Software analogy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;States&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Molecule concentrations, cell counts, organ volumes, biomarkers&lt;/td&gt;
&lt;td&gt;Domain states, stored fields&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Processes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reactions, transport mechanisms, discrete events&lt;/td&gt;
&lt;td&gt;Business logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Organ sizes, blood flows, interaction constants, conditions&lt;/td&gt;
&lt;td&gt;Configuration settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Equations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rate laws, transport equations, empirical rules&lt;/td&gt;
&lt;td&gt;Algorithms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Solver&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ODE integrator running the system dynamics&lt;/td&gt;
&lt;td&gt;Runtime / execution engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Datasets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Experimental, clinical, literature data&lt;/td&gt;
&lt;td&gt;Test data, fixtures, databases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tasks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dose optimization, prediction, parameter estimation, validation&lt;/td&gt;
&lt;td&gt;Use cases, automated tests&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This mapping isn't perfect, but it highlights a useful perspective: QSP models aren't just collections of equations—they're systems with states, logic, data, and tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Simple Example
&lt;/h3&gt;

&lt;p&gt;To make this more concrete, let's look at an example - far smaller than what modelers deal with in practice, but enough to illustrate the key principles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszvbopyey6jo657p9if0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszvbopyey6jo657p9if0.png" alt="Alcohol metabolism model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Fig 1. A toy QSP model of alcohol metabolism.&lt;/strong&gt; This minimal example is used to illustrate model structure; real QSP models can include thousands of components and interactions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this example, ethanol is consumed twice (state &lt;strong&gt;&lt;em&gt;Alc_g&lt;/em&gt;&lt;/strong&gt;), absorbed into the bloodstream (&lt;strong&gt;&lt;em&gt;Alc_b&lt;/em&gt;&lt;/strong&gt;), metabolized into acetaldehyde (&lt;strong&gt;&lt;em&gt;AcHc&lt;/em&gt;&lt;/strong&gt;), and then further converted into acetate (&lt;strong&gt;&lt;em&gt;Acet&lt;/em&gt;&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;In ODE form, the model's core dynamics are:&lt;br&gt;


&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;d(Alcg)dt=−vabsAlc,d(Alcb⋅blood)dt=vabsAlc−vADH,d(AcHc⋅blood)dt=vADH−vALDH,d(Acet⋅blood)dt=vALDH.
\begin{align*}
\frac{d(Alc_g)}{dt} &amp;amp; = -vabs_{Alc},\\
\frac{d(Alc_b \cdot blood)}{dt} &amp;amp; = vabs_{Alc} - v_{ADH},\\
\frac{d(AcHc \cdot blood)}{dt} &amp;amp; = v_{ADH} - v_{ALDH},\\
\frac{d(Acet \cdot blood)}{dt} &amp;amp; = v_{ALDH}.
\end{align*}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-r"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;oo&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;cHc&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;oo&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ce&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;oo&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ab&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ab&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;where&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;vabsAlc=kabsAlc⋅Alcg,vADH=VmaxADH⋅AlcbKmADH+Alcb⋅blood,vALDH=VmaxALDH⋅AcHcKmALDH+AcHc⋅blood.
\begin{align*}
vabs_{Alc} &amp;amp; = kabs_{Alc} \cdot Alc_g,\\
v_{ADH} &amp;amp; =  \frac{Vmax_{ADH} \cdot Alc_b}{Km_{ADH} + Alc_b} \cdot blood,\\
v_{ALDH} &amp;amp; = \frac{Vmax_{ALDH} \cdot AcHc}{Km_{ALDH} + AcHc} \cdot blood.
\end{align*}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-r"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ab&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;kab&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;Vma&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;oo&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;cHc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;Vma&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;DH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;cHc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;oo&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4gilya59gfo77w55djx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4gilya59gfo77w55djx.png" alt="Alcohol metabolism simulation results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Fig 2. Demo run of the toy alcohol model.&lt;/strong&gt; Results are illustrative and qualitative, not quantitative. Definitely not medical advice (or bartending advice).&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond the Core Equations
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;real-world projects&lt;/strong&gt;, the mathematical core is important but just the part of the model. A complete, reproducible modeling package also needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Annotations&lt;/strong&gt; - units, explanations, and key assumptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parameter sets &amp;amp; datasets&lt;/strong&gt; - conditions, doses, patient characteristics, and data for calibration and validation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solver settings &amp;amp; metadata&lt;/strong&gt; - numerical settings and project history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without these, results are not reproducible, and the model cannot be properly evaluated or reused. Here, we'll keep our focus on the core structure of models rather than all the surrounding layers.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Popular Tools and How They Store Models
&lt;/h2&gt;

&lt;p&gt;At their core, QSP models are systems of algebraic and differential equations. But the moment we try to implement such a model on a computer, things get trickier. Equations need to be expressed in a very specific way - as functions, arguments, and expressions tailored for a particular programming language or solver.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyu8jr0p1nwq6eza2qxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyu8jr0p1nwq6eza2qxi.png" alt="Raw scripting Matlab code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Fig 3. Example of raw scripting in Matlab.&lt;/strong&gt; Model logic (right) and simulation script (left) live in separate files but are still entangled. The model carries redundant syntax just to satisfy MATLAB and cannot be directly reused in another language or tool. Updating the model code may result in changes in the simulation script.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To make life easier, many tools introduce their own &lt;strong&gt;Domain Specific Languages (DSL)&lt;/strong&gt; or rely on &lt;strong&gt;macros&lt;/strong&gt;. In essence, we're still writing ODEs, but now they are expressed in a more compact, structured form. This makes the model easier to read and sometimes separates the model description from the execution code - a small but important step toward better clarity and maintainability.&lt;/p&gt;

&lt;p&gt;However, this approach still has its drawbacks. As models grow larger, ODE-based code becomes difficult to maintain: it resists modularization, and even small changes may require edits in multiple places or restructuring the equations themselves. On top of that, the notation is far from intuitive for biologists or pharmacologists, who tend to think in terms of reactions, metabolites, and pathways rather than ODEs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1cw6pzs9f519ozksmva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1cw6pzs9f519ozksmva.png" alt="ODE based DSL, mrgsolve"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Fig 4. Example of ODE based DSL in mrgsolve.&lt;/strong&gt; The model is expressed as a macro-like C++ dialect, which makes it close to the solver and mathematically transparent. The syntax is tool-specific and difficult to parse or convert, limiting portability beyond mrgsolve (and partially NONMEM).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One way around this is the &lt;strong&gt;process-based approach&lt;/strong&gt; describing the model in terms of processes that involve metabolites, reactions, compartments and other entities. The software then generates the ODE system automatically (e.g., from tables or a custom DSL) right before simulation. This approach reduces manual edits, enables modularity, and lowers the risk of mistakes.&lt;br&gt;&lt;br&gt;
The trade-off? You need to adjust your modeling mindset. The equation-level view is hidden behind generation, and you need an explicit build pipeline. Still, this method has been influential &lt;a href="https://sbml.org/" rel="noopener noreferrer"&gt;SBML&lt;/a&gt; is one example born from such thinking.&lt;/p&gt;

&lt;p&gt;To make models even more approachable, some tools offer &lt;strong&gt;visual modeling&lt;/strong&gt; showing the model as a map or process graph. Great for accessibility, less so for large-scale version control.&lt;/p&gt;

&lt;p&gt;In practice, different tools offer different interaction styles. For small models, it doesn't matter much which you choose. As complexity grows, the differences become critical-impacting &lt;strong&gt;usability, versioning, and collaboration&lt;/strong&gt;. For example, comparing two versions, reusing components, or organizing a modular model is often much easier in a process-based DSL than in raw ODE code.&lt;/p&gt;

&lt;p&gt;Broadly, user–model interaction falls into these categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raw scripting&lt;/strong&gt; - Pure code in a &lt;strong&gt;general-purpose language&lt;/strong&gt; (MATLAB, Julia, R, Python). Maximum flexibility, minimal standardization. Equations are coded directly; solvers may also be custom-built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual modeling&lt;/strong&gt; - The user &lt;strong&gt;draws diagrams&lt;/strong&gt;, with equations and parameters hidden in annotations (e.g., SimBiology, JDesigner). Great for visualization, poor for Git diffs and mass editing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DSL-based modeling (ODE- or process-based)&lt;/strong&gt; - A dedicated &lt;strong&gt;intermediate language&lt;/strong&gt;. Balances readability, structure, and flexibility (e.g., mrgsolve, Heta); plus separating the &lt;strong&gt;model layer&lt;/strong&gt; from the &lt;strong&gt;execution layer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table-based modeling&lt;/strong&gt; - The model is defined via &lt;strong&gt;series of spreadsheets&lt;/strong&gt;. The idea is similar to a DSL but avoids the need to memorize syntax. Readable, but limited in expressing complex logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixed modeling&lt;/strong&gt; - Combinations such as tables + DSL, or tables + diagrams, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfxw9k719btb9v2pjgg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfxw9k719btb9v2pjgg5.png" alt="Visual modeling SimBiology code snippet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Fig 5. Example of visual modeling in SimBiology.&lt;/strong&gt; Visual diagrams make it easier for beginners and biologists to start modeling, but serious work still requires editing mathematical details hidden in tables and formulas. The binary storage format complicates version control and collaboration, while large models quickly become cumbersome as diagrams grow too complex to manage effectively.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Ends Up on Disk: Project Storage Formats
&lt;/h3&gt;

&lt;p&gt;Beyond the way models are written (authoring approach), &lt;strong&gt;storage format&lt;/strong&gt; matters, especially for collaboration, exchange, and version control. Some platforms store everything in a single file; others use multiple files in different formats. In QSP, storage formats often differ across tools and are rarely interoperable.&lt;/p&gt;

&lt;p&gt;Broad storage format categories for QSP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Binary formats&lt;/strong&gt; - Not human-readable, hard to diff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proprietary text formats&lt;/strong&gt; - Can be opened in a text editor, but structure is obscure and not meant for manual editing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured formats&lt;/strong&gt; - Based on open standards (XML, SBML, JSON, YAML). Easier to parse and transform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human-readable text&lt;/strong&gt; - Best for Git and team workflows, but still needs a parser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;way you write a model&lt;/strong&gt; affects how easy it is to work with, how accessible it is for collaborators, and how reusable the code becomes. The &lt;strong&gt;way you store&lt;/strong&gt; a project determines whether it is Git-friendly, easy to compare across versions, and possible to translate into other tools and formats. Both layers matter — and problems often come from confusing or conflating the two.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7d7zkgxt7a257hq3jtx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7d7zkgxt7a257hq3jtx.png" alt="HetaSimulator code snippet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Fig 6. Example for process-based DSL. Code for HetaSimulator.&lt;/strong&gt; Heta offers a solver- and scripting-independent way to describe models and works well with version control. Support modules and namespaces. However, the format is niche, less familiar to those used to ODEs, and may feel harder to adopt outside its community. Requires a specific &lt;a href="https://hetalang.github.io/hetacompiler" rel="noopener noreferrer"&gt;translator&lt;/a&gt; for use across applications.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tool Matrix: Authoring, Storage, and Interfaces
&lt;/h3&gt;

&lt;p&gt;QSP has been steadily evolving since &lt;strong&gt;around 2010&lt;/strong&gt;. Many of the tools used today originated in neighboring fields such as Systems Biology, PBPK, and PK/PD. Some of them were &lt;strong&gt;adapted&lt;/strong&gt; to serve QSP needs, while others were &lt;strong&gt;developed&lt;/strong&gt; from scratch.&lt;/p&gt;

&lt;p&gt;The table below summarizes key tools in the QSP landscape. Tools are included based on three criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mentioned&lt;/strong&gt; in QSP software reviews (i.e. &lt;a href="https://doi.org/10.1002/psp4.12373" rel="noopener noreferrer"&gt;QSP tools review, CPT-PSP, 2018&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Positioned&lt;/strong&gt; as QSP tools in docs or case studies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Designed&lt;/strong&gt; for solving dynamics, not just auxiliary tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Software&lt;/th&gt;
&lt;th&gt;Interaction mode&lt;/th&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Model/project file format&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;Initial scope&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.mathworks.com/help/simbio/index.html" rel="noopener noreferrer"&gt;SimBiology&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Visual, Tables&lt;/td&gt;
&lt;td&gt;Process-based&lt;/td&gt;
&lt;td&gt;Binary (.sbproj)&lt;/td&gt;
&lt;td&gt;GUI, Scripting (Matlab)&lt;/td&gt;
&lt;td&gt;SB, QSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw MATLAB&lt;/td&gt;
&lt;td&gt;Raw scripting&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Human-readable (.m)&lt;/td&gt;
&lt;td&gt;Scripting (Matlab)&lt;/td&gt;
&lt;td&gt;General purpose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://hetalang.github.io" rel="noopener noreferrer"&gt;HetaSimulator&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;DSL, Tables&lt;/td&gt;
&lt;td&gt;Process-based&lt;/td&gt;
&lt;td&gt;Human-readable (.heta)&lt;/td&gt;
&lt;td&gt;Scripting (Julia)&lt;/td&gt;
&lt;td&gt;QSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.pumas.ai/stable/" rel="noopener noreferrer"&gt;Pumas&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;DSL&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Human-readable (.jl)&lt;/td&gt;
&lt;td&gt;Scripting (Julia)&lt;/td&gt;
&lt;td&gt;PK/PD, QSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.open-systems-pharmacology.org/" rel="noopener noreferrer"&gt;PK-Sim/MoBi&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tables, Visual&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Structured (.xml, .pkml)&lt;/td&gt;
&lt;td&gt;Scripting (R)&lt;/td&gt;
&lt;td&gt;PBPK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://iqrtools.intiquan.com/" rel="noopener noreferrer"&gt;IQR Tools&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;DSL&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Human-readable (.txt)&lt;/td&gt;
&lt;td&gt;Scripting (R)&lt;/td&gt;
&lt;td&gt;PK/PD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://mrgsolve.org/" rel="noopener noreferrer"&gt;mrgsolve&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;DSL&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Human-readable (.mod)&lt;/td&gt;
&lt;td&gt;Scripting (R)&lt;/td&gt;
&lt;td&gt;PK/PD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://sourceforge.net/projects/dbsolve/" rel="noopener noreferrer"&gt;DBSolve&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Mixed: DSL + Tables&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Proprietary text (.slv)&lt;/td&gt;
&lt;td&gt;GUI&lt;/td&gt;
&lt;td&gt;SB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.berkeleymadonna.com/" rel="noopener noreferrer"&gt;Berkeley Madonna&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Mixed: DSL + Tables&lt;/td&gt;
&lt;td&gt;ODE-based, Process-based&lt;/td&gt;
&lt;td&gt;Proprietary text (.mmd)&lt;/td&gt;
&lt;td&gt;GUI&lt;/td&gt;
&lt;td&gt;General purpose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.certara.com/software/simcyp-pbpk/" rel="noopener noreferrer"&gt;SimCYP&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;td&gt;ODE-based (*restricted)&lt;/td&gt;
&lt;td&gt;Proprietary text (.wksz)&lt;/td&gt;
&lt;td&gt;GUI, Scripting (R)&lt;/td&gt;
&lt;td&gt;PBPK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.simulations-plus.com/software/gastroplus/" rel="noopener noreferrer"&gt;GastroPlus&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;td&gt;ODE-based (*restricted)&lt;/td&gt;
&lt;td&gt;Binary (.gpj)&lt;/td&gt;
&lt;td&gt;GUI&lt;/td&gt;
&lt;td&gt;PBPK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://monolixsuite.slp-software.com/monolix/2024R1/" rel="noopener noreferrer"&gt;Monolix&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Mixed: DSL, Tables&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Human-readable (.mlxtran, .txt)&lt;/td&gt;
&lt;td&gt;GUI, Scripting (R, Python)&lt;/td&gt;
&lt;td&gt;PK/PD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.iconplc.com/solutions/technologies/nonmem" rel="noopener noreferrer"&gt;NONMEM&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Mixed: DSL, Tables&lt;/td&gt;
&lt;td&gt;ODE-based&lt;/td&gt;
&lt;td&gt;Human-readable (.ctl, .mod)&lt;/td&gt;
&lt;td&gt;CLI, Scripting (PsN/Pirana)&lt;/td&gt;
&lt;td&gt;PK/PD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://jdesigner.sourceforge.net/Site/JDesigner.html" rel="noopener noreferrer"&gt;JDesigner&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Visual&lt;/td&gt;
&lt;td&gt;Process-based&lt;/td&gt;
&lt;td&gt;Binary (.jdes)&lt;/td&gt;
&lt;td&gt;GUI&lt;/td&gt;
&lt;td&gt;SB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;* restricted - limited access to the ODE structure; pre-generated for drug distribution models.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What this comparison actually tells us? Looking across tools, a few patterns stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability gap.&lt;/strong&gt; Most ecosystems define their own project and model formats; moving between them usually means partial rewrites or lossy conversions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authoring ≠ storage.&lt;/strong&gt; A convenient way to write a model (visual editor, macro DSL) doesn't guarantee a format that's easy to diff, review, or translate. Many tools couple authoring and storage tightly, which locks projects to a runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opacity hurts teamwork.&lt;/strong&gt; Binary or proprietary text bundles are hard to compare, branch, and merge; they don't play well with Git, code review, or CI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling pain&lt;/strong&gt;. ODE-centric code scales poorly: small structural tweaks (e.g., making a volume dynamic) ripple across many equations. Visual maps don't scale either—large diagrams become navigation mazes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skill barrier and mental models.&lt;/strong&gt; Biologists think in terms of reactions, metabolites, pathways; engineers and solvers consume equations. Many tools force one side to work in the other side's mental model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams, this creates a mix of problems: onboarding and &lt;strong&gt;knowledge transfer become slower&lt;/strong&gt;, &lt;strong&gt;reproducibility suffers&lt;/strong&gt; when parts of the logic are hidden in GUIs or project files, every new dataset or mechanism &lt;strong&gt;increases the cost of changes&lt;/strong&gt;, and projects gradually become &lt;strong&gt;locked into&lt;/strong&gt; a single vendor's toolset.&lt;/p&gt;

&lt;p&gt;The bigger issue isn’t the formats themselves, but the &lt;strong&gt;isolation of the communities&lt;/strong&gt; that use them. QSP modeling is already demanding: you need biology, math, data, statistics. Few people have the energy to master more than one tool, so most pick one and stay there. &lt;strong&gt;The circle closes&lt;/strong&gt;: groups can't share because formats don't match, and formats don't match because each tool is tuned to its own little world. The way out doesn't have to come only from research groups or pharma companies—software &lt;strong&gt;developers can play a big role&lt;/strong&gt; in breaking these walls too.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Some argue that modeling is not the same as coding, so engineering principles don't apply. Others say that closed, tool-specific formats are just "normal" for such specialized fields. I believe we can and should do better. What do you think?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>modeling</category>
      <category>datascience</category>
      <category>pharma</category>
    </item>
  </channel>
</rss>
