dhavalkadia-fda commited on
Commit
f137b36
·
verified ·
1 Parent(s): 128403f

Upload 65 files

Browse files
.gitattributes CHANGED
@@ -35,3 +35,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  assets/AIM-CU-Overview.drawio.png filter=lfs diff=lfs merge=lfs -text
37
  docs/build/latex/aim-cu.pdf filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  assets/AIM-CU-Overview.drawio.png filter=lfs diff=lfs merge=lfs -text
37
  docs/build/latex/aim-cu.pdf filter=lfs diff=lfs merge=lfs -text
38
+ assets/AIM-CU-Overview.png filter=lfs diff=lfs merge=lfs -text
39
+ assets/ui.png filter=lfs diff=lfs merge=lfs -text
40
+ figure/fig_plot_average_metric.png filter=lfs diff=lfs merge=lfs -text
41
+ figure/fig_plot_cusum_chart.png filter=lfs diff=lfs merge=lfs -text
42
+ figure/fig_plot_data_distribution.png filter=lfs diff=lfs merge=lfs -text
43
+ figure/fig_table_h_k_arl1.png filter=lfs diff=lfs merge=lfs -text
Dockerfile CHANGED
@@ -22,6 +22,7 @@ RUN Rscript -e "install.packages('spc')"
22
  WORKDIR /app/src/package
23
  COPY . /app/
24
 
25
- RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
 
26
 
27
  CMD ["python3", "app.py"]
 
22
  WORKDIR /app/src/package
23
  COPY . /app/
24
 
25
+ RUN pip install --use-pep517 --no-cache-dir --upgrade -r /app/requirements.txt
26
+ RUN pip install --upgrade gradio gradio_client
27
 
28
  CMD ["python3", "app.py"]
README.rst CHANGED
@@ -1,20 +1,40 @@
1
- AIM-CU : A CUSUM-based tool for AI Monitoring
2
  ======
3
 
4
- .. image:: assets/AIM-CU-Overview.drawio.png
5
  :width: 800
6
  :align: center
7
  :alt: AIM-CU flowchart
8
 
9
- Monitoring a clinically deployed AI device to detect performance drift is an essential step to
10
- ensure the safety and effectiveness of AI.
 
11
 
12
- AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU).
13
  AIM-CU computes:
14
 
15
  * The parameter choices for change-point detection based on an acceptable false alarm rate
16
  * Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  Code execution
19
  --------------
20
  Clone AIM-CU repository.
@@ -36,17 +56,30 @@ Run AIM-CU.
36
 
37
  .. code-block:: shell
38
 
 
39
  python3 app.py
40
 
41
  Open the URL http://0.0.0.0:7860 that is running the AIM-CU locally.
42
 
43
  Example code execution
44
  ----------------------
45
- Example code can be run in a Jupyter Notebook after opening it with ``jupyter notebook`` command from ``/src/package`` directory.
46
 
47
  Demo
48
  ----
49
- AIM-CU can also be run through the demo available at https://huggingface.co/spaces/didsr/AIM-CU. If Space is paused, click on Restart button.
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  Related References
52
  ------------------
@@ -58,7 +91,6 @@ Related References
58
 
59
  * Smriti Prathapan, Ravi K. Samala, Nathan Hadjiyski, Pierre‑François D’Haese, Nicholas Petrick, Jana Delfino, Fabien Maldonado, Brandon Nelson, Ghada Zamzmi, Phuong Nguyen, Yelena Yesha, and Berkman Sahiner, "Post-market Monitoring of AI-enabled Medical Devices for Radiology and Healthcare Applications" (FDA-UMiami Collaboration Poster, September 2023)
60
 
61
-
62
  Disclaimer
63
  ----------
64
  This software and documentation was developed at the Food and Drug Administration (FDA) by employees of the Federal Government in the course of their official duties. Pursuant to Title 17, Section 105 of the United States Code, this work is not subject to copyright protection and is in the public domain. Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software or derivatives, and to permit persons to whom the Software is furnished to do so. FDA assumes no responsibility whatsoever for use by other parties of the Software, its source code, documentation or compiled executables, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Further, use of this code in no way implies endorsement by the FDA or confers any advantage in regulatory decisions. Although this software can be redistributed and/or modified freely, we ask that any derivative works bear some notice that they are derived from it, and any modified versions bear some notice that they have been modified.
 
1
+ AIM-CU: A CUSUM-based tool for AI Monitoring
2
  ======
3
 
4
+ .. image:: assets/AIM-CU-Overview.png
5
  :width: 800
6
  :align: center
7
  :alt: AIM-CU flowchart
8
 
9
+ Monitoring a clinically deployed AI device to detect performance drift is an essential step to ensure the safety and effectiveness of AI.
10
+
11
+ AIM-CU is a statistical tool for AI monitoring based on a cumulative sum (AIM-CU) approach.
12
 
 
13
  AIM-CU computes:
14
 
15
  * The parameter choices for change-point detection based on an acceptable false alarm rate
16
  * Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.
17
 
18
+ System setup
19
+ ------------
20
+ Make sure R is installed in the system. There is no specific version that this relies on. Here we have used R version 4.1.2 (2021-11-01).
21
+ Instructions for Linux (the below setup is only performed in Linux):
22
+
23
+ .. code-block:: shell
24
+
25
+ wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
26
+ add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"
27
+ apt-get install -y --no-install-recommends r-base r-base-dev
28
+
29
+ # setup R configs
30
+ echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile
31
+ Rscript -e "install.packages('ggplot2')"
32
+ Rscript -e "install.packages('hexbin')"
33
+ Rscript -e "install.packages('lazyeval')"
34
+ Rscript -e "install.packages('cusumcharter')"
35
+ Rscript -e "install.packages('RcppCNPy')"
36
+ Rscript -e "install.packages('spc')"
37
+
38
  Code execution
39
  --------------
40
  Clone AIM-CU repository.
 
56
 
57
  .. code-block:: shell
58
 
59
+ cd src/package
60
  python3 app.py
61
 
62
  Open the URL http://0.0.0.0:7860 that is running the AIM-CU locally.
63
 
64
  Example code execution
65
  ----------------------
66
+ Example code can be run through Jupyter Notebook. Do this by entering the ``jupyter notebook`` command from the ``/src/package/`` directory. The tool is designed to be used through a GUI, not from the console.
67
 
68
  Demo
69
  ----
70
+ AIM-CU can also be run through the demo available at https://huggingface.co/spaces/didsr/AIM-CU. If Space is paused, click on Restart button. Note: this Space uses a custom Docker container; build may break due to latest package updates pulled by HuggingFace.
71
+
72
+ Usability
73
+ ---------
74
+ * Example AI output CSV file is available as `config/spec-60-60.csv <config/spec-60-60.csv>`_ to be uploaded in monitoring phase.
75
+
76
+ * Workflow instruction to run the tool is available at bottom-left of UI.
77
+
78
+ * Sample UI output is available at `assets/ui.png <assets/ui.png>`_.
79
+
80
+ * Setting ``control:save_figure`` to ``true`` from `config.toml <config/config.toml>`_ will save tables and plots in `figure/ <figure/>`_.
81
+
82
+ * Running AIM-CU usually only takes a few seconds, and it does not require a GPU to run.
83
 
84
  Related References
85
  ------------------
 
91
 
92
  * Smriti Prathapan, Ravi K. Samala, Nathan Hadjiyski, Pierre‑François D’Haese, Nicholas Petrick, Jana Delfino, Fabien Maldonado, Brandon Nelson, Ghada Zamzmi, Phuong Nguyen, Yelena Yesha, and Berkman Sahiner, "Post-market Monitoring of AI-enabled Medical Devices for Radiology and Healthcare Applications" (FDA-UMiami Collaboration Poster, September 2023)
93
 
 
94
  Disclaimer
95
  ----------
96
  This software and documentation was developed at the Food and Drug Administration (FDA) by employees of the Federal Government in the course of their official duties. Pursuant to Title 17, Section 105 of the United States Code, this work is not subject to copyright protection and is in the public domain. Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software or derivatives, and to permit persons to whom the Software is furnished to do so. FDA assumes no responsibility whatsoever for use by other parties of the Software, its source code, documentation or compiled executables, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Further, use of this code in no way implies endorsement by the FDA or confers any advantage in regulatory decisions. Although this software can be redistributed and/or modified freely, we ask that any derivative works bear some notice that they are derived from it, and any modified versions bear some notice that they have been modified.
assets/AIM-CU-Overview.png ADDED

Git LFS Details

  • SHA256: 9a833bf26041308d91f66125c1f05c13280e86f1822d0d23a4148a127fc43599
  • Pointer size: 131 Bytes
  • Size of remote file: 377 kB
assets/AIM-CU-Overview.xml ADDED
The diff for this file is too large to render. See raw diff
 
assets/ui.png ADDED

Git LFS Details

  • SHA256: 1756e32abf9a6757a9795eab1385978e3f7c4a4424648e6d30379060939bb7ff
  • Pointer size: 131 Bytes
  • Size of remote file: 658 kB
docs/build/html/_sources/index.rst.txt CHANGED
@@ -8,40 +8,83 @@ AIM-CU documentation
8
 
9
  A CUSUM-based tool for AI Monitoring
10
 
11
- AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU). AIM-CU computes:
 
 
 
 
12
 
13
  * The parameter choices for change-point detection based on an acceptable false alarm rate
14
  * Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  Code execution
17
- ------------------
18
  Clone AIM-CU repository.
19
 
20
  .. code-block:: shell
21
 
22
- git clone https://github.com/DIDSR/AIM-CU.git
23
 
24
  Run the following commands to install required dependencies (Python = 3.10 is used).
25
 
26
  .. code-block:: shell
27
 
28
- apt-get -y install python3
29
- apt-get -y install pip
30
- cd AIM-CU
31
- pip install -r requirements.txt
32
 
33
  Run AIM-CU.
34
 
35
  .. code-block:: shell
36
 
37
- python3 app.py
 
38
 
39
  Open the URL http://0.0.0.0:7860 that is running the AIM-CU locally.
40
 
 
 
 
 
41
  Demo
42
- ------------------
43
  AIM-CU can also be run through the demo available at https://huggingface.co/spaces/didsr/AIM-CU. If Space is paused, click on Restart button.
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  .. toctree::
46
  :maxdepth: 2
47
  :caption: Contents:
@@ -49,4 +92,8 @@ AIM-CU can also be run through the demo available at https://huggingface.co/spac
49
  ref_method
50
  ref_cusum
51
  ref_theoretical
52
- ref_utils
 
 
 
 
 
8
 
9
  A CUSUM-based tool for AI Monitoring
10
 
11
+ Monitoring a clinically deployed AI device to detect performance drift is an essential step to ensure the safety and effectiveness of AI.
12
+
13
+ AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU).
14
+
15
+ AIM-CU computes:
16
 
17
  * The parameter choices for change-point detection based on an acceptable false alarm rate
18
  * Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.
19
 
20
+ System setup
21
+ ------------
22
+ Make sure R is installed in the system. Instructions for linux (the below setup is only performed in linux):
23
+
24
+ .. code-block:: shell
25
+
26
+ wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
27
+ add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"
28
+ apt-get install -y --no-install-recommends r-base r-base-dev
29
+
30
+ # setup R configs
31
+ echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile
32
+ Rscript -e "install.packages('ggplot2')"
33
+ Rscript -e "install.packages('hexbin')"
34
+ Rscript -e "install.packages('lazyeval')"
35
+ Rscript -e "install.packages('cusumcharter')"
36
+ Rscript -e "install.packages('RcppCNPy')"
37
+ Rscript -e "install.packages('spc')"
38
+
39
  Code execution
40
+ --------------
41
  Clone AIM-CU repository.
42
 
43
  .. code-block:: shell
44
 
45
+ git clone https://github.com/DIDSR/AIM-CU.git
46
 
47
  Run the following commands to install required dependencies (Python = 3.10 is used).
48
 
49
  .. code-block:: shell
50
 
51
+ apt-get -y install python3
52
+ apt-get -y install pip
53
+ cd AIM-CU
54
+ pip install -r requirements.txt
55
 
56
  Run AIM-CU.
57
 
58
  .. code-block:: shell
59
 
60
+ cd src/package
61
+ python3 app.py
62
 
63
  Open the URL http://0.0.0.0:7860 that is running the AIM-CU locally.
64
 
65
+ Example code execution
66
+ ----------------------
67
+ Example code can be run in a Jupyter Notebook after opening it with ``jupyter notebook`` command from ``/src/package/`` directory. The tool is designed to used through UI, not from console.
68
+
69
  Demo
70
+ ----
71
  AIM-CU can also be run through the demo available at https://huggingface.co/spaces/didsr/AIM-CU. If Space is paused, click on Restart button.
72
 
73
+ Usability
74
+ ---------
75
+ * Example AI output CSV file is available as `config/spec-60-60.csv <config/spec-60-60.csv>`_ to be uploaded in monitoring phase.
76
+
77
+ * Workflow instruction to run the tool is available at bottom-left of UI.
78
+
79
+ * Sample UI output is available at `assets/ui.png <assets/ui.png>`_.
80
+
81
+ * Setting ``control:save_figure`` to ``true`` from `config.toml <config/config.toml>`_ will save tables and plots in `figure/ <figure/>`_.
82
+
83
+ * Running AIM-CU does not take time longer than a few seconds, and it does not require GPU.
84
+
85
+ AIM-CU
86
+ ------
87
+
88
  .. toctree::
89
  :maxdepth: 2
90
  :caption: Contents:
 
92
  ref_method
93
  ref_cusum
94
  ref_theoretical
95
+ ref_utils
96
+
97
+ Disclaimer
98
+ ----------
99
+ This software and documentation was developed at the Food and Drug Administration (FDA) by employees of the Federal Government in the course of their official duties. Pursuant to Title 17, Section 105 of the United States Code, this work is not subject to copyright protection and is in the public domain. Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software or derivatives, and to permit persons to whom the Software is furnished to do so. FDA assumes no responsibility whatsoever for use by other parties of the Software, its source code, documentation or compiled executables, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Further, use of this code in no way implies endorsement by the FDA or confers any advantage in regulatory decisions. Although this software can be redistributed and/or modified freely, we ask that any derivative works bear some notice that they are derived from it, and any modified versions bear some notice that they have been modified.
docs/build/html/index.html CHANGED
@@ -36,11 +36,31 @@
36
  <section id="aim-cu-documentation">
37
  <h1>AIM-CU documentation<a class="headerlink" href="#aim-cu-documentation" title="Link to this heading">¶</a></h1>
38
  <p>A CUSUM-based tool for AI Monitoring</p>
39
- <p>AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU). AIM-CU computes:</p>
 
 
40
  <ul class="simple">
41
  <li><p>The parameter choices for change-point detection based on an acceptable false alarm rate</p></li>
42
  <li><p>Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.</p></li>
43
  </ul>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  <section id="code-execution">
45
  <h2>Code execution<a class="headerlink" href="#code-execution" title="Link to this heading">¶</a></h2>
46
  <p>Clone AIM-CU repository.</p>
@@ -55,14 +75,32 @@ pip<span class="w"> </span>install<span class="w"> </span>-r<span class="w"> </s
55
  </pre></div>
56
  </div>
57
  <p>Run AIM-CU.</p>
58
- <div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>python3<span class="w"> </span>app.py
 
59
  </pre></div>
60
  </div>
61
  <p>Open the URL <a class="reference external" href="http://0.0.0.0:7860">http://0.0.0.0:7860</a> that is running the AIM-CU locally.</p>
62
  </section>
 
 
 
 
63
  <section id="demo">
64
  <h2>Demo<a class="headerlink" href="#demo" title="Link to this heading">¶</a></h2>
65
  <p>AIM-CU can also be run through the demo available at <a class="reference external" href="https://huggingface.co/spaces/didsr/AIM-CU">https://huggingface.co/spaces/didsr/AIM-CU</a>. If Space is paused, click on Restart button.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  <div class="toctree-wrapper compound">
67
  <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
68
  <ul>
@@ -91,6 +129,10 @@ pip<span class="w"> </span>install<span class="w"> </span>-r<span class="w"> </s
91
  </ul>
92
  </div>
93
  </section>
 
 
 
 
94
  </section>
95
 
96
 
 
36
  <section id="aim-cu-documentation">
37
  <h1>AIM-CU documentation<a class="headerlink" href="#aim-cu-documentation" title="Link to this heading">¶</a></h1>
38
  <p>A CUSUM-based tool for AI Monitoring</p>
39
+ <p>Monitoring a clinically deployed AI device to detect performance drift is an essential step to ensure the safety and effectiveness of AI.</p>
40
+ <p>AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU).</p>
41
+ <p>AIM-CU computes:</p>
42
  <ul class="simple">
43
  <li><p>The parameter choices for change-point detection based on an acceptable false alarm rate</p></li>
44
  <li><p>Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.</p></li>
45
  </ul>
46
+ <section id="system-setup">
47
+ <h2>System setup<a class="headerlink" href="#system-setup" title="Link to this heading">¶</a></h2>
48
+ <p>Make sure R is installed in the system. Instructions for linux (the below setup is only performed in linux):</p>
49
+ <div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>wget<span class="w"> </span>-qO-<span class="w"> </span>https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc<span class="w"> </span><span class="p">|</span><span class="w"> </span>tee<span class="w"> </span>-a<span class="w"> </span>/etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
50
+ add-apt-repository<span class="w"> </span><span class="s2">&quot;deb https://cloud.r-project.org/bin/linux/ubuntu </span><span class="k">$(</span>lsb_release<span class="w"> </span>-cs<span class="k">)</span><span class="s2">-cran40/&quot;</span>
51
+ apt-get<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>--no-install-recommends<span class="w"> </span>r-base<span class="w"> </span>r-base-dev
52
+
53
+ <span class="c1"># setup R configs</span>
54
+ <span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;r &lt;- getOption(&#39;repos&#39;); r[&#39;CRAN&#39;] &lt;- &#39;http://cran.us.r-project.org&#39;; options(repos = r);&quot;</span><span class="w"> </span>&gt;<span class="w"> </span>~/.Rprofile
55
+ Rscript<span class="w"> </span>-e<span class="w"> </span><span class="s2">&quot;install.packages(&#39;ggplot2&#39;)&quot;</span>
56
+ Rscript<span class="w"> </span>-e<span class="w"> </span><span class="s2">&quot;install.packages(&#39;hexbin&#39;)&quot;</span>
57
+ Rscript<span class="w"> </span>-e<span class="w"> </span><span class="s2">&quot;install.packages(&#39;lazyeval&#39;)&quot;</span>
58
+ Rscript<span class="w"> </span>-e<span class="w"> </span><span class="s2">&quot;install.packages(&#39;cusumcharter&#39;)&quot;</span>
59
+ Rscript<span class="w"> </span>-e<span class="w"> </span><span class="s2">&quot;install.packages(&#39;RcppCNPy&#39;)&quot;</span>
60
+ Rscript<span class="w"> </span>-e<span class="w"> </span><span class="s2">&quot;install.packages(&#39;spc&#39;)&quot;</span>
61
+ </pre></div>
62
+ </div>
63
+ </section>
64
  <section id="code-execution">
65
  <h2>Code execution<a class="headerlink" href="#code-execution" title="Link to this heading">¶</a></h2>
66
  <p>Clone AIM-CU repository.</p>
 
75
  </pre></div>
76
  </div>
77
  <p>Run AIM-CU.</p>
78
+ <div class="highlight-shell notranslate"><div class="highlight"><pre><span></span><span class="nb">cd</span><span class="w"> </span>src/package
79
+ python3<span class="w"> </span>app.py
80
  </pre></div>
81
  </div>
82
  <p>Open the URL <a class="reference external" href="http://0.0.0.0:7860">http://0.0.0.0:7860</a> that is running the AIM-CU locally.</p>
83
  </section>
84
+ <section id="example-code-execution">
85
+ <h2>Example code execution<a class="headerlink" href="#example-code-execution" title="Link to this heading">¶</a></h2>
86
+ <p>Example code can be run in a Jupyter Notebook after opening it with <code class="docutils literal notranslate"><span class="pre">jupyter</span> <span class="pre">notebook</span></code> command from <code class="docutils literal notranslate"><span class="pre">/src/package/</span></code> directory. The tool is designed to used through UI, not from console.</p>
87
+ </section>
88
  <section id="demo">
89
  <h2>Demo<a class="headerlink" href="#demo" title="Link to this heading">¶</a></h2>
90
  <p>AIM-CU can also be run through the demo available at <a class="reference external" href="https://huggingface.co/spaces/didsr/AIM-CU">https://huggingface.co/spaces/didsr/AIM-CU</a>. If Space is paused, click on Restart button.</p>
91
+ </section>
92
+ <section id="usability">
93
+ <h2>Usability<a class="headerlink" href="#usability" title="Link to this heading">¶</a></h2>
94
+ <ul class="simple">
95
+ <li><p>Example AI output CSV file is available as <a class="reference external" href="config/spec-60-60.csv">config/spec-60-60.csv</a> to be uploaded in monitoring phase.</p></li>
96
+ <li><p>Workflow instruction to run the tool is available at bottom-left of UI.</p></li>
97
+ <li><p>Sample UI output is available at <a class="reference external" href="assets/ui.png">assets/ui.png</a>.</p></li>
98
+ <li><p>Setting <code class="docutils literal notranslate"><span class="pre">control:save_figure</span></code> to <code class="docutils literal notranslate"><span class="pre">true</span></code> from <a class="reference external" href="config/config.toml">config.toml</a> will save tables and plots in <a class="reference external" href="figure/">figure/</a>.</p></li>
99
+ <li><p>Running AIM-CU does not take time longer than a few seconds, and it does not require GPU.</p></li>
100
+ </ul>
101
+ </section>
102
+ <section id="aim-cu">
103
+ <h2>AIM-CU<a class="headerlink" href="#aim-cu" title="Link to this heading">¶</a></h2>
104
  <div class="toctree-wrapper compound">
105
  <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
106
  <ul>
 
129
  </ul>
130
  </div>
131
  </section>
132
+ <section id="disclaimer">
133
+ <h2>Disclaimer<a class="headerlink" href="#disclaimer" title="Link to this heading">¶</a></h2>
134
+ <p>This software and documentation was developed at the Food and Drug Administration (FDA) by employees of the Federal Government in the course of their official duties. Pursuant to Title 17, Section 105 of the United States Code, this work is not subject to copyright protection and is in the public domain. Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software or derivatives, and to permit persons to whom the Software is furnished to do so. FDA assumes no responsibility whatsoever for use by other parties of the Software, its source code, documentation or compiled executables, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Further, use of this code in no way implies endorsement by the FDA or confers any advantage in regulatory decisions. Although this software can be redistributed and/or modified freely, we ask that any derivative works bear some notice that they are derived from it, and any modified versions bear some notice that they have been modified.</p>
135
+ </section>
136
  </section>
137
 
138
 
docs/build/html/searchindex.js CHANGED
@@ -1 +1 @@
1
- Search.setIndex({"alltitles": {"AIM-CU documentation": [[0, null]], "ARLTheoretical": [[3, null]], "CUSUM": [[1, null]], "CUSUM chart": [[2, "cusum-chart"]], "CUSUM parameters": [[2, "cusum-parameters"], [2, "id1"]], "Code execution": [[0, "code-execution"]], "Contents:": [[0, null]], "Demo": [[0, "demo"]], "Methods": [[2, null]], "Utils": [[4, null]]}, "docnames": ["index", "ref_cusum", "ref_method", "ref_theoretical", "ref_utils"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst", "ref_cusum.rst", "ref_method.rst", "ref_theoretical.rst", "ref_utils.rst"], "indexentries": {"change_detection() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.change_detection", false]], "compute_cusum() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.compute_cusum", false]], "cusum (class in package.cusum)": [[1, "package.cusum.CUSUM", false]], "initialize() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.initialize", false]], "module": [[1, "module-package.cusum", false]], "package.cusum": [[1, "module-package.cusum", false]], "plot_cusum_plotly() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.plot_cusum_plotly", false]], "plot_input_metric_plotly() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.plot_input_metric_plotly", false]], "plot_input_metric_plotly_raw() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.plot_input_metric_plotly_raw", false]], "set_df_metric_csv() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.set_df_metric_csv", false]], "set_df_metric_default() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.set_df_metric_default", false]], "set_init_stats() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.set_init_stats", false]], "set_timeline() (package.cusum.cusum method)": [[1, "package.cusum.CUSUM.set_timeline", false]]}, "objects": {"package": [[3, 0, 0, "-", "ARLTheoretical"], [1, 0, 0, "-", "cusum"], [4, 0, 0, "-", "utils"]], "package.ARLTheoretical": [[3, 1, 1, "", "get_ARL_1"], [3, 1, 1, "", "get_ARL_1_h_mu1_k"], [3, 1, 1, "", "get_ref_value"], [3, 1, 1, "", "get_ref_value_k"]], "package.cusum": [[1, 2, 1, "", "CUSUM"]], "package.cusum.CUSUM": [[1, 3, 1, "", "change_detection"], [1, 3, 1, "", "compute_cusum"], [1, 3, 1, "", "initialize"], [1, 3, 1, "", "plot_cusum_plotly"], [1, 3, 1, "", "plot_input_metric_plotly"], [1, 3, 1, "", "plot_input_metric_plotly_raw"], [1, 3, 1, "", "set_df_metric_csv"], [1, 3, 1, "", "set_df_metric_default"], [1, 3, 1, "", "set_init_stats"], [1, 3, 1, "", "set_timeline"]], "package.utils": [[4, 1, 1, "", "get_greattable_as_html"], [4, 1, 1, "", "populate_summary_table_ARL0_k"], [4, 1, 1, "", "populate_summary_table_ARL1_k"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"], "2": ["py", "class", "Python class"], "3": ["py", "method", "Python method"]}, "objtypes": {"0": "py:module", "1": "py:function", "2": "py:class", "3": "py:method"}, "terms": {"0": [0, 1, 2], "1": 2, "10": 0, "3": 0, "30": 1, "4": [1, 2], "5": [1, 2], "7860": 0, "A": [0, 1, 2], "If": 0, "In": 1, "The": [0, 2], "To": 2, "_": 2, "accept": 0, "accumul": 2, "across": 1, "ai": [0, 1], "alarm": 0, "along": 3, "also": 0, "an": [0, 1], "app": 0, "apt": 0, "ar": [1, 2], "arl0": [3, 4], "arl1": [3, 4], "arl_0": [2, 3], "arl_1": [2, 3], "arltheoret": [0, 4], "assign": 1, "author": [1, 3], "avail": 0, "awai": 2, "ax": 1, "base": 0, "befor": 2, "being": 2, "between": 4, "button": 0, "calcul": [1, 2, 3], "can": 0, "cd": 0, "chang": [0, 1, 2], "change_detect": 1, "chart": 0, "choic": [0, 2], "class": 1, "click": 0, "clone": 0, "co": 0, "com": 0, "comma": 1, "command": 0, "comput": [0, 1, 2], "compute_cusum": 1, "configur": 1, "consid": 1, "control": [1, 2], "csv": 1, "cumul": [0, 1, 2], "cusum": 0, "d": 2, "dai": 1, "data": [1, 3, 4], "data_csv": 1, "datafram": [1, 3, 4], "default": [1, 2], "delai": [0, 3], "denot": 2, "depend": 0, "descript": 2, "detect": [0, 1, 2, 3], "determin": 2, "deviat": [1, 2], "df": 4, "dict_arl0_k": [3, 4], "dictionari": [3, 4], "didsr": 0, "differ": [2, 4], "dimension": 1, "displac": 0, "drift": 2, "e": 2, "estim": 0, "exampl": 1, "fals": [0, 2], "figur": 1, "file": 1, "float": [1, 3, 4], "follow": 0, "format": 4, "from": [0, 2, 4], "function": 1, "get": [0, 3, 4], "get_arl_1": [0, 3], "get_arl_1_h_mu1_k": [0, 3], "get_greattable_as_html": [0, 4], "get_ref_valu": [0, 3], "get_ref_value_k": [0, 3], "git": 0, "github": 0, "given": [0, 3], "go": 1, "graph": 1, "great_tabl": 4, "gt": 4, "h": [2, 3, 4], "handl": 4, "hat": 2, "hi": 2, "html": 4, "http": 0, "huggingfac": 0, "i": [0, 1, 2, 3], "individu": 2, "init_dai": 1, "initi": 1, "input": 1, "instal": 0, "int": 1, "intend": 3, "interest": [1, 2], "its": [1, 4], "k": [1, 2, 3, 4], "label": 1, "let": 2, "limit": 2, "list": [1, 3], "list_arl_0": 3, "lo": 2, "local": 0, "magnitud": [1, 2], "map": 4, "max": 2, "mean": [1, 2, 3], "method": 0, "metric": [0, 1, 2], "monitor": [0, 1, 2], "mu": 2, "mu1": 3, "mu_": 2, "mu_0": 1, "multiindex": 4, "ndarrai": 1, "neg": [1, 2], "none": 1, "normal": [1, 2, 3, 4], "normalized_ref_valu": 1, "normalized_threshold": 1, "np": 1, "number": [1, 2], "object": 1, "observ": [1, 2], "one": [1, 2], "open": 0, "oper": 4, "option": 1, "ordereddict": [3, 4], "output": 1, "packag": [1, 3, 4], "panda": 4, "paramet": [0, 1, 3, 4], "paus": 0, "pd": [3, 4], "perform": [0, 1, 2], "phase": 1, "pip": 0, "plot": 1, "plot_cusum_plotli": 1, "plot_input_metric_plotli": 1, "plot_input_metric_plotly_raw": 1, "plotli": 1, "point": 0, "popul": 4, "populate_summary_table_arl0_k": [0, 4], "populate_summary_table_arl1_k": [0, 4], "posit": [1, 2], "prathapan": [1, 3], "pre_change_dai": 1, "process": [1, 2], "provid": [1, 3], "py": 0, "python": 0, "python3": 0, "quantiti": 2, "r": 0, "rate": 0, "read": 1, "refer": [1, 2, 3], "relat": [1, 2], "rendera": 4, "repositori": 0, "requir": 0, "respect": 4, "restart": 0, "return": [1, 3, 4], "run": 0, "s_": 2, "s_hi": 2, "s_lo": 2, "scatter": 1, "scheme": 2, "separ": 1, "set": 1, "set_df_metric_csv": 1, "set_df_metric_default": 1, "set_init_stat": 1, "set_timelin": 1, "shift": 3, "shift_in_mean": 3, "side": 2, "sigma_": 2, "signal": 2, "smriti": [1, 3], "space": 0, "specif": 4, "stabl": 1, "standard": [1, 2], "statist": 0, "structur": 1, "sum": [0, 1, 2], "summary_table_df_arl0_k": 4, "summary_table_df_arl1_k": 4, "tabl": [3, 4], "target": [0, 2], "textfileread": 1, "thi": 2, "those": 0, "threshold": [1, 2, 3, 4], "through": 0, "time": 2, "timelin": 1, "tool": 0, "true": 2, "tupl": [1, 3], "two": [1, 2], "txt": 0, "type": [1, 3, 4], "unit": [1, 2], "url": 0, "us": [0, 1], "util": 0, "valu": [1, 2, 3, 4], "when": [1, 2], "where": [2, 3], "which": 2, "x": 1, "x_d": 2, "y": 0, "\u03bc_in": 2, "\u03c3_in": 2}, "titles": ["AIM-CU documentation", "CUSUM", "Methods", "ARLTheoretical", "Utils"], "titleterms": {"aim": 0, "arltheoret": 3, "chart": 2, "code": 0, "content": 0, "cu": 0, "cusum": [1, 2], "demo": 0, "document": 0, "execut": 0, "method": 2, "paramet": 2, "util": 4}})
 
1
+ Search.setIndex({"alltitles": {"AIM-CU": [[0, "aim-cu"]], "AIM-CU documentation": [[0, null]], "ARLTheoretical": [[3, null]], "CUSUM": [[1, null]], "CUSUM chart": [[2, "cusum-chart"]], "CUSUM parameters": [[2, "cusum-parameters"], [2, "id1"]], "Code execution": [[0, "code-execution"]], "Contents:": [[0, null]], "Demo": [[0, "demo"]], "Disclaimer": [[0, "disclaimer"]], "Example code execution": [[0, "example-code-execution"]], "Methods": [[2, null]], "System setup": [[0, "system-setup"]], "Usability": [[0, "usability"]], "Utils": [[4, null]]}, "docnames": ["index", "ref_cusum", "ref_method", "ref_theoretical", "ref_utils"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst", "ref_cusum.rst", "ref_method.rst", "ref_theoretical.rst", "ref_utils.rst"], "indexentries": {}, "objects": {"package": [[3, 0, 0, "-", "ARLTheoretical"], [1, 0, 0, "-", "cusum"], [4, 0, 0, "-", "utils"]], "package.ARLTheoretical": [[3, 1, 1, "", "get_ARL_1"], [3, 1, 1, "", "get_ARL_1_h_mu1_k"], [3, 1, 1, "", "get_ref_value"], [3, 1, 1, "", "get_ref_value_k"]], "package.cusum": [[1, 2, 1, "", "CUSUM"]], "package.cusum.CUSUM": [[1, 3, 1, "", "change_detection"], [1, 3, 1, "", "compute_cusum"], [1, 3, 1, "", "initialize"], [1, 3, 1, "", "plot_cusum_plotly"], [1, 3, 1, "", "plot_input_metric_plotly"], [1, 3, 1, "", "plot_input_metric_plotly_raw"], [1, 3, 1, "", "set_df_metric_csv"], [1, 3, 1, "", "set_df_metric_default"], [1, 3, 1, "", "set_init_stats"], [1, 3, 1, "", "set_timeline"]], "package.utils": [[4, 1, 1, "", "get_greattable_as_html"], [4, 1, 1, "", "populate_summary_table_ARL0_k"], [4, 1, 1, "", "populate_summary_table_ARL1_k"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"], "2": ["py", "class", "Python class"], "3": ["py", "method", "Python method"]}, "objtypes": {"0": "py:module", "1": "py:function", "2": "py:class", "3": "py:method"}, "terms": {"0": [0, 1, 2], "1": 2, "10": 0, "105": 0, "17": 0, "3": 0, "30": 1, "4": [1, 2], "5": [1, 2], "60": 0, "7860": 0, "A": [0, 1, 2], "If": 0, "In": 1, "The": [0, 2], "To": 2, "_": 2, "about": 0, "accept": 0, "accumul": 2, "across": 1, "add": 0, "administr": 0, "advantag": 0, "after": 0, "ai": [0, 1], "alarm": 0, "along": 3, "also": 0, "although": 0, "an": [0, 1], "ani": 0, "app": 0, "apt": 0, "ar": [0, 1, 2], "arl0": [3, 4], "arl1": [3, 4], "arl_0": [2, 3], "arl_1": [2, 3], "arltheoret": [0, 4], "asc": 0, "ask": 0, "asset": 0, "assign": 1, "assum": 0, "author": [1, 3], "avail": 0, "awai": 2, "ax": 1, "base": 0, "bear": 0, "been": 0, "befor": 2, "being": 2, "below": 0, "between": 4, "bin": 0, "bottom": 0, "button": 0, "c": 0, "calcul": [1, 2, 3], "can": 0, "cd": 0, "chang": [0, 1, 2], "change_detect": 1, "characterist": 0, "charg": 0, "chart": 0, "choic": [0, 2], "class": 1, "click": 0, "clinic": 0, "clone": 0, "cloud": 0, "co": 0, "com": 0, "comma": 1, "command": 0, "compil": 0, "comput": [0, 1, 2], "compute_cusum": 1, "confer": 0, "config": 0, "configur": 1, "consid": 1, "consol": 0, "control": [0, 1, 2], "copi": 0, "copyright": 0, "cours": 0, "cran": 0, "cran40": 0, "cran_ubuntu_kei": 0, "csv": [0, 1], "cumul": [0, 1, 2], "cusum": 0, "cusumchart": 0, "d": [0, 2], "dai": 1, "data": [1, 3, 4], "data_csv": 1, "datafram": [1, 3, 4], "deal": 0, "deb": 0, "decis": 0, "default": [1, 2], "delai": [0, 3], "denot": 2, "depend": 0, "deploi": 0, "deriv": 0, "descript": 2, "design": 0, "detect": [0, 1, 2, 3], "determin": 2, "dev": 0, "develop": 0, "deviat": [1, 2], "devic": 0, "df": 4, "dict_arl0_k": [3, 4], "dictionari": [3, 4], "didsr": 0, "differ": [2, 4], "dimension": 1, "directori": 0, "displac": 0, "distribut": 0, "do": 0, "doe": 0, "domain": 0, "drift": [0, 2], "drug": 0, "duti": 0, "e": [0, 2], "echo": 0, "effect": 0, "employe": 0, "endors": 0, "ensur": 0, "essenti": 0, "estim": 0, "etc": 0, "exampl": 1, "express": 0, "fals": [0, 2], "fda": 0, "feder": 0, "few": 0, "figur": [0, 1], "file": [0, 1], "float": [1, 3, 4], "follow": 0, "food": 0, "format": 4, "free": 0, "freeli": 0, "from": [0, 2, 4], "function": 1, "furnish": 0, "further": 0, "get": [0, 3, 4], "get_arl_1": [0, 3], "get_arl_1_h_mu1_k": [0, 3], "get_greattable_as_html": [0, 4], "get_ref_valu": [0, 3], "get_ref_value_k": [0, 3], "getopt": 0, "ggplot2": 0, "git": 0, "github": 0, "given": [0, 3], "go": 1, "govern": 0, "gpg": 0, "gpu": 0, "grant": 0, "graph": 1, "great_tabl": 4, "gt": 4, "guarante": 0, "h": [2, 3, 4], "handl": 4, "hat": 2, "have": 0, "herebi": 0, "hexbin": 0, "hi": 2, "html": 4, "http": 0, "huggingfac": 0, "i": [0, 1, 2, 3], "impli": 0, "includ": 0, "individu": 2, "init_dai": 1, "initi": 1, "input": 1, "instal": 0, "instruct": 0, "int": 1, "intend": 3, "interest": [1, 2], "its": [0, 1, 4], "jupyt": 0, "k": [1, 2, 3, 4], "label": 1, "lazyev": 0, "left": 0, "let": 2, "limit": [0, 2], "linux": 0, "list": [1, 3], "list_arl_0": 3, "lo": 2, "local": 0, "longer": 0, "lsb_releas": 0, "magnitud": [1, 2], "make": 0, "map": 4, "marutter_pubkei": 0, "max": 2, "mean": [1, 2, 3], "merg": 0, "method": 0, "metric": [0, 1, 2], "modifi": 0, "monitor": [0, 1, 2], "mu": 2, "mu1": 3, "mu_": 2, "mu_0": 1, "multiindex": 4, "ndarrai": 1, "neg": [1, 2], "none": 1, "normal": [1, 2, 3, 4], "normalized_ref_valu": 1, "normalized_threshold": 1, "notebook": 0, "notic": 0, "np": 1, "number": [1, 2], "object": 1, "observ": [1, 2], "obtain": 0, "offici": 0, "one": [1, 2], "onli": 0, "open": 0, "oper": 4, "option": [0, 1], "ordereddict": [3, 4], "org": 0, "other": 0, "output": [0, 1], "packag": [0, 1, 3, 4], "panda": 4, "paramet": [0, 1, 3, 4], "parti": 0, "paus": 0, "pd": [3, 4], "perform": [0, 1, 2], "permiss": 0, "permit": 0, "person": 0, "phase": [0, 1], "pip": 0, "plot": [0, 1], "plot_cusum_plotli": 1, "plot_input_metric_plotli": 1, "plot_input_metric_plotly_raw": 1, "plotli": 1, "png": 0, "point": 0, "popul": 4, "populate_summary_table_arl0_k": [0, 4], "populate_summary_table_arl1_k": [0, 4], "posit": [1, 2], "prathapan": [1, 3], "pre_change_dai": 1, "process": [1, 2], "project": 0, "protect": 0, "provid": [1, 3], "public": 0, "publish": 0, "pursuant": 0, "py": 0, "python": 0, "python3": 0, "qo": 0, "qualiti": 0, "quantiti": 2, "r": 0, "rate": 0, "rcppcnpy": 0, "read": 1, "recommend": 0, "redistribut": 0, "refer": [1, 2, 3], "regulatori": 0, "relat": [1, 2], "reliabl": 0, "rendera": 4, "repo": 0, "repositori": 0, "requir": 0, "respect": 4, "respons": 0, "restart": 0, "restrict": 0, "return": [1, 3, 4], "right": 0, "rprofil": 0, "rscript": 0, "run": 0, "s_": 2, "s_hi": 2, "s_lo": 2, "safeti": 0, "sampl": 0, "save": 0, "save_figur": 0, "scatter": 1, "scheme": 2, "second": 0, "section": 0, "sell": 0, "separ": 1, "set": [0, 1], "set_df_metric_csv": 1, "set_df_metric_default": 1, "set_init_stat": 1, "set_timelin": 1, "shift": 3, "shift_in_mean": 3, "side": 2, "sigma_": 2, "signal": 2, "smriti": [1, 3], "so": 0, "softwar": 0, "some": 0, "sourc": 0, "space": 0, "spc": 0, "spec": 0, "specif": 4, "src": 0, "stabl": 1, "standard": [1, 2], "state": 0, "statist": 0, "step": 0, "structur": 1, "subject": 0, "sublicens": 0, "sum": [0, 1, 2], "summary_table_df_arl0_k": 4, "summary_table_df_arl1_k": 4, "sure": 0, "tabl": [0, 3, 4], "take": 0, "target": [0, 2], "tee": 0, "textfileread": 1, "than": 0, "thei": 0, "thi": [0, 2], "those": 0, "threshold": [1, 2, 3, 4], "through": 0, "time": [0, 2], "timelin": 1, "titl": 0, "toml": 0, "tool": 0, "true": [0, 2], "trust": 0, "tupl": [1, 3], "two": [1, 2], "txt": 0, "type": [1, 3, 4], "u": 0, "ubuntu": 0, "ui": 0, "unit": [0, 1, 2], "upload": 0, "url": 0, "us": [0, 1], "util": 0, "valu": [1, 2, 3, 4], "version": 0, "wa": 0, "wai": 0, "we": 0, "wget": 0, "whatsoev": 0, "when": [1, 2], "where": [2, 3], "which": 2, "whom": 0, "without": 0, "work": 0, "workflow": 0, "x": 1, "x_d": 2, "y": 0, "\u03bc_in": 2, "\u03c3_in": 2}, "titles": ["AIM-CU documentation", "CUSUM", "Methods", "ARLTheoretical", "Utils"], "titleterms": {"aim": 0, "arltheoret": 3, "chart": 2, "code": 0, "content": 0, "cu": 0, "cusum": [1, 2], "demo": 0, "disclaim": 0, "document": 0, "exampl": 0, "execut": 0, "method": 2, "paramet": 2, "setup": 0, "system": 0, "usabl": 0, "util": 4}})
docs/build/latex/aim-cu.pdf CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:93dfcb8bab790019e595646e65c50e4d9dd98f6edac6c5460a9c8e1714f75ab9
3
- size 214164
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:43d5c4317b6206ef1cbbecf90ef47516a795e6fccecd683b267962e9cb3c6c64
3
+ size 242546
docs/source/index.rst CHANGED
@@ -8,40 +8,83 @@ AIM-CU documentation
8
 
9
  A CUSUM-based tool for AI Monitoring
10
 
11
- AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU). AIM-CU computes:
 
 
 
 
12
 
13
  * The parameter choices for change-point detection based on an acceptable false alarm rate
14
  * Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  Code execution
17
- ------------------
18
  Clone AIM-CU repository.
19
 
20
  .. code-block:: shell
21
 
22
- git clone https://github.com/DIDSR/AIM-CU.git
23
 
24
  Run the following commands to install required dependencies (Python = 3.10 is used).
25
 
26
  .. code-block:: shell
27
 
28
- apt-get -y install python3
29
- apt-get -y install pip
30
- cd AIM-CU
31
- pip install -r requirements.txt
32
 
33
  Run AIM-CU.
34
 
35
  .. code-block:: shell
36
 
37
- python3 app.py
 
38
 
39
  Open the URL http://0.0.0.0:7860 that is running the AIM-CU locally.
40
 
 
 
 
 
41
  Demo
42
- ------------------
43
  AIM-CU can also be run through the demo available at https://huggingface.co/spaces/didsr/AIM-CU. If Space is paused, click on Restart button.
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  .. toctree::
46
  :maxdepth: 2
47
  :caption: Contents:
@@ -49,4 +92,8 @@ AIM-CU can also be run through the demo available at https://huggingface.co/spac
49
  ref_method
50
  ref_cusum
51
  ref_theoretical
52
- ref_utils
 
 
 
 
 
8
 
9
  A CUSUM-based tool for AI Monitoring
10
 
11
+ Monitoring a clinically deployed AI device to detect performance drift is an essential step to ensure the safety and effectiveness of AI.
12
+
13
+ AIM-CU is a statistical tool for AI monitoring using cumulative sum (AIM-CU).
14
+
15
+ AIM-CU computes:
16
 
17
  * The parameter choices for change-point detection based on an acceptable false alarm rate
18
  * Detection delay estimates for a given displacement of the performance metric from the target for those parameter choices.
19
 
20
+ System setup
21
+ ------------
22
+ Make sure R is installed in the system. Instructions for linux (the below setup is only performed in linux):
23
+
24
+ .. code-block:: shell
25
+
26
+ wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
27
+ add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"
28
+ apt-get install -y --no-install-recommends r-base r-base-dev
29
+
30
+ # setup R configs
31
+ echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile
32
+ Rscript -e "install.packages('ggplot2')"
33
+ Rscript -e "install.packages('hexbin')"
34
+ Rscript -e "install.packages('lazyeval')"
35
+ Rscript -e "install.packages('cusumcharter')"
36
+ Rscript -e "install.packages('RcppCNPy')"
37
+ Rscript -e "install.packages('spc')"
38
+
39
  Code execution
40
+ --------------
41
  Clone AIM-CU repository.
42
 
43
  .. code-block:: shell
44
 
45
+ git clone https://github.com/DIDSR/AIM-CU.git
46
 
47
  Run the following commands to install required dependencies (Python = 3.10 is used).
48
 
49
  .. code-block:: shell
50
 
51
+ apt-get -y install python3
52
+ apt-get -y install pip
53
+ cd AIM-CU
54
+ pip install -r requirements.txt
55
 
56
  Run AIM-CU.
57
 
58
  .. code-block:: shell
59
 
60
+ cd src/package
61
+ python3 app.py
62
 
63
  Open the URL http://0.0.0.0:7860 that is running the AIM-CU locally.
64
 
65
+ Example code execution
66
+ ----------------------
67
+ Example code can be run in a Jupyter Notebook after opening it with ``jupyter notebook`` command from ``/src/package/`` directory. The tool is designed to used through UI, not from console.
68
+
69
  Demo
70
+ ----
71
  AIM-CU can also be run through the demo available at https://huggingface.co/spaces/didsr/AIM-CU. If Space is paused, click on Restart button.
72
 
73
+ Usability
74
+ ---------
75
+ * Example AI output CSV file is available as `config/spec-60-60.csv <config/spec-60-60.csv>`_ to be uploaded in monitoring phase.
76
+
77
+ * Workflow instruction to run the tool is available at bottom-left of UI.
78
+
79
+ * Sample UI output is available at `assets/ui.png <assets/ui.png>`_.
80
+
81
+ * Setting ``control:save_figure`` to ``true`` from `config.toml <config/config.toml>`_ will save tables and plots in `figure/ <figure/>`_.
82
+
83
+ * Running AIM-CU does not take time longer than a few seconds, and it does not require GPU.
84
+
85
+ AIM-CU
86
+ ------
87
+
88
  .. toctree::
89
  :maxdepth: 2
90
  :caption: Contents:
 
92
  ref_method
93
  ref_cusum
94
  ref_theoretical
95
+ ref_utils
96
+
97
+ Disclaimer
98
+ ----------
99
+ This software and documentation was developed at the Food and Drug Administration (FDA) by employees of the Federal Government in the course of their official duties. Pursuant to Title 17, Section 105 of the United States Code, this work is not subject to copyright protection and is in the public domain. Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software or derivatives, and to permit persons to whom the Software is furnished to do so. FDA assumes no responsibility whatsoever for use by other parties of the Software, its source code, documentation or compiled executables, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Further, use of this code in no way implies endorsement by the FDA or confers any advantage in regulatory decisions. Although this software can be redistributed and/or modified freely, we ask that any derivative works bear some notice that they are derived from it, and any modified versions bear some notice that they have been modified.
figure/fig_plot_average_metric.png ADDED

Git LFS Details

  • SHA256: 1550f5352c267d17257fbdf5f12520ee0f82edd97ed9993f00cb3ddf0f278639
  • Pointer size: 131 Bytes
  • Size of remote file: 286 kB
figure/fig_plot_cusum_chart.png ADDED

Git LFS Details

  • SHA256: 70af8726360192683f937130bbf6ffac47ce01a2c02c0fd54997b5d475489004
  • Pointer size: 131 Bytes
  • Size of remote file: 505 kB
figure/fig_plot_data_distribution.png ADDED

Git LFS Details

  • SHA256: 404f9bbc06cbf2b46d0950bc3cbc3d1e2626d69d391fe26ae5b52074f335dcd8
  • Pointer size: 131 Bytes
  • Size of remote file: 649 kB
figure/fig_table_h_arl0_k.png ADDED
figure/fig_table_h_k_arl1.png ADDED

Git LFS Details

  • SHA256: 643bc7931c2672a2e26a8986e920fabcb44151d82bfc855444707f5c426fee66
  • Pointer size: 131 Bytes
  • Size of remote file: 418 kB
src/package/ARLTheoretical.py CHANGED
@@ -129,7 +129,7 @@ def get_ARL_1(
129
  utils = rpackages.importr("utils")
130
  spc = rpackages.importr("spc")
131
  # select a mirror for R packages
132
- utils.chooseCRANmirror(ind=1) # select the first mirror in the list
133
 
134
  # R package names
135
  packnames = ("ggplot2", "hexbin", "lazyeval", "cusumcharter", "RcppCNPy", "spc")
 
129
  utils = rpackages.importr("utils")
130
  spc = rpackages.importr("spc")
131
  # select a mirror for R packages
132
+ # utils.chooseCRANmirror(ind=1) # select the first mirror in the list
133
 
134
  # R package names
135
  packnames = ("ggplot2", "hexbin", "lazyeval", "cusumcharter", "RcppCNPy", "spc")
src/package/__pycache__/ARLTheoretical.cpython-310.pyc CHANGED
Binary files a/src/package/__pycache__/ARLTheoretical.cpython-310.pyc and b/src/package/__pycache__/ARLTheoretical.cpython-310.pyc differ
 
src/package/__pycache__/cusum.cpython-310.pyc CHANGED
Binary files a/src/package/__pycache__/cusum.cpython-310.pyc and b/src/package/__pycache__/cusum.cpython-310.pyc differ
 
src/package/__pycache__/utils.cpython-310.pyc CHANGED
Binary files a/src/package/__pycache__/utils.cpython-310.pyc and b/src/package/__pycache__/utils.cpython-310.pyc differ
 
src/package/app.py CHANGED
@@ -1,5 +1,8 @@
1
  """
2
  Gradio user interface for AIM-CU
 
 
 
3
  """
4
 
5
  import os
@@ -21,11 +24,11 @@ def set_init_days(
21
  file_csv_metric: gr.File, init_days: str
22
  ) -> tuple[float, float, go.Figure]:
23
  """
24
- Set initial days and get in-control mean and standard deviation.
25
 
26
  Args:
27
  file_csv_metric (gr.File): CSV file with metric data
28
- init_days (str): initial days to calculate in-control mean and standard deviation
29
 
30
  Returns:
31
  tuple[float, float, go.Figure]: In-control mean and standard deviation, and observation data plot.
@@ -174,7 +177,7 @@ with gr.Blocks(
174
  with gr.Row():
175
  with gr.Column():
176
  gr.Markdown(f"""
177
- ### Phase I:
178
  """) # noqa: F541
179
 
180
  gr.Markdown(f"""
@@ -183,12 +186,12 @@ with gr.Blocks(
183
 
184
  # load the CSV file with specifities across days
185
  csv_file_metric = gr.File(
186
- label="Upload the AI output",
187
  )
188
 
189
  with gr.Row():
190
  with gr.Column():
191
- init_days = gr.Textbox(label="Initial days", placeholder="30")
192
  with gr.Column():
193
  button_calculate_incontrol_params = gr.Button(
194
  "Calculate parameters"
@@ -271,8 +274,8 @@ with gr.Blocks(
271
  gr.Markdown(f"""
272
  ### Workflow:
273
  Phase I:
274
- - Upload the AI output.
275
- - Enter initial days.
276
  - Calculate parameters.
277
  - Check parameter choices in Phase 1, for Phase 2. (optional)
278
 
@@ -286,7 +289,7 @@ with gr.Blocks(
286
  )
287
  with gr.Column():
288
  gr.Markdown(f"""
289
- ### Phase II:
290
  Performance drift detection plots, pre- and post-change distribution with respect to the performance drift detected.
291
  """) # noqa: F541
292
 
 
1
  """
2
  Gradio user interface for AIM-CU
3
+
4
+ Disclaimer:
5
+ This software and documentation was developed at the Food and Drug Administration (FDA) by employees of the Federal Government in the course of their official duties. Pursuant to Title 17, Section 105 of the United States Code, this work is not subject to copyright protection and is in the public domain. Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software or derivatives, and to permit persons to whom the Software is furnished to do so. FDA assumes no responsibility whatsoever for use by other parties of the Software, its source code, documentation or compiled executables, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic. Further, use of this code in no way implies endorsement by the FDA or confers any advantage in regulatory decisions. Although this software can be redistributed and/or modified freely, we ask that any derivative works bear some notice that they are derived from it, and any modified versions bear some notice that they have been modified.
6
  """
7
 
8
  import os
 
24
  file_csv_metric: gr.File, init_days: str
25
  ) -> tuple[float, float, go.Figure]:
26
  """
27
+ Set number of baseline observations and get in-control mean and standard deviation.
28
 
29
  Args:
30
  file_csv_metric (gr.File): CSV file with metric data
31
+ init_days (str): Number of baseline observations to calculate in-control mean and standard deviation
32
 
33
  Returns:
34
  tuple[float, float, go.Figure]: In-control mean and standard deviation, and observation data plot.
 
177
  with gr.Row():
178
  with gr.Column():
179
  gr.Markdown(f"""
180
+ ### Initialization:
181
  """) # noqa: F541
182
 
183
  gr.Markdown(f"""
 
186
 
187
  # load the CSV file with specifities across days
188
  csv_file_metric = gr.File(
189
+ label="Upload the AI output (CSV file)",
190
  )
191
 
192
  with gr.Row():
193
  with gr.Column():
194
+ init_days = gr.Textbox(label="Number of baseline observations", placeholder="30")
195
  with gr.Column():
196
  button_calculate_incontrol_params = gr.Button(
197
  "Calculate parameters"
 
274
  gr.Markdown(f"""
275
  ### Workflow:
276
  Phase I:
277
+ - Upload the AI output (CSV file).
278
+ - Enter number of baseline observations.
279
  - Calculate parameters.
280
  - Check parameter choices in Phase 1, for Phase 2. (optional)
281
 
 
289
  )
290
  with gr.Column():
291
  gr.Markdown(f"""
292
+ ### Monitoring:
293
  Performance drift detection plots, pre- and post-change distribution with respect to the performance drift detected.
294
  """) # noqa: F541
295
 
src/package/cusum.py CHANGED
@@ -60,10 +60,10 @@ class CUSUM:
60
 
61
  def set_init_stats(self, init_days: int) -> None:
62
  """
63
- Use initial days to calculate in-control mean and standard deviation.
64
 
65
  Args:
66
- init_days (int, optional): Initial days when observations are considered stable. Defaults to 30.
67
  """
68
  self.init_days = init_days
69
 
@@ -171,7 +171,7 @@ class CUSUM:
171
  normalized_ref_value (float, optional): Normalized reference value for detecting a unit standard deviation change in mean of the process. Defaults to 0.5.
172
  normalized_threshold (float, optional): Normalized threshold. Defaults to 4.
173
  """
174
- self.pre_change_days = self.init_days # This is the #initial days that we assume to be in-control - user enters or default = 30
175
 
176
  ref_val = normalized_ref_value
177
  control_limit = normalized_threshold
@@ -313,7 +313,7 @@ class CUSUM:
313
  fig.add_vrect(
314
  x0=0,
315
  x1=self.init_days,
316
- annotation_text="Initial days",
317
  annotation_position="top right",
318
  fillcolor="palegreen",
319
  opacity=0.25,
@@ -326,7 +326,7 @@ class CUSUM:
326
  "font": {"size": font_size_title, "weight": "bold"},
327
  },
328
  xaxis_title={
329
- "text": "Length of observations",
330
  "font": {"size": font_size_legend, "weight": "bold"},
331
  },
332
  yaxis_title={
@@ -361,13 +361,7 @@ class CUSUM:
361
  y2 = self.data[self.pre_change_days : self.total_days]
362
  mean_y2 = np.mean(y2)
363
 
364
- fig = make_subplots(
365
- rows=1,
366
- cols=2,
367
- column_widths=[0.7, 0.3],
368
- shared_yaxes=True,
369
- horizontal_spacing=0.02,
370
- )
371
 
372
  font_size_title = 20
373
  font_size_legend = 18
@@ -382,8 +376,6 @@ class CUSUM:
382
  marker=dict(color="darkturquoise", size=10),
383
  opacity=0.4,
384
  ),
385
- row=1,
386
- col=1,
387
  )
388
  fig.add_trace(
389
  go.Scatter(
@@ -394,8 +386,6 @@ class CUSUM:
394
  marker=dict(color="coral", size=10),
395
  opacity=0.4,
396
  ),
397
- row=1,
398
- col=1,
399
  )
400
 
401
  # add horizontal lines
@@ -407,8 +397,6 @@ class CUSUM:
407
  name="In-control mean",
408
  line=dict(color="darkturquoise", dash="dash"),
409
  ),
410
- row=1,
411
- col=1,
412
  )
413
  fig.add_trace(
414
  go.Scatter(
@@ -418,8 +406,6 @@ class CUSUM:
418
  name="Out-of-control mean",
419
  line=dict(color="coral", dash="dash"),
420
  ),
421
- row=1,
422
- col=1,
423
  )
424
 
425
  # add vertical line
@@ -432,17 +418,15 @@ class CUSUM:
432
  line=dict(color="grey", dash="dash"),
433
  # textfont=dict(size=18)
434
  ),
435
- row=1,
436
- col=1,
437
  )
438
 
439
  fig.update_layout(
440
  title={
441
- "text": "Pre- and post-change observations and their respective histograms",
442
  "font": {"size": font_size_title, "weight": "bold"},
443
  },
444
  xaxis_title={
445
- "text": "Length of observations",
446
  "font": {"size": font_size_legend, "weight": "bold"},
447
  },
448
  yaxis_title={
@@ -458,64 +442,64 @@ class CUSUM:
458
  legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
459
  )
460
 
461
- # add histogram (like marginal histogram)
462
- nbinsx = 15 # 6
463
-
464
- # add subplots
465
- fig.add_trace(
466
- go.Histogram(
467
- y=self.data[: self.pre_change_days],
468
- nbinsy=nbinsx,
469
- # name=f"""Pre-change S<sub>p</sub>""",
470
- showlegend=False,
471
- marker=dict(color="mediumturquoise"),
472
- opacity=0.4,
473
- orientation="h",
474
- ),
475
- row=1,
476
- col=2,
477
- )
478
-
479
- fig.add_trace(
480
- go.Histogram(
481
- y=self.data[self.pre_change_days : self.total_days],
482
- nbinsy=nbinsx,
483
- # name=f"""Post-change S<sub>p</sub>""",
484
- showlegend=False,
485
- marker=dict(color="coral"),
486
- opacity=0.4,
487
- orientation="h",
488
- ),
489
- row=1,
490
- col=2,
491
- )
492
-
493
- fig.add_trace(
494
- go.Scatter(
495
- x=[0, 20], # [! y_max can should be used]
496
- y=[
497
- np.mean(self.data[: self.pre_change_days]),
498
- np.mean(self.data[: self.pre_change_days]),
499
- ],
500
- mode="lines",
501
- # name="Reference mean",
502
- showlegend=False,
503
- line=dict(color="mediumturquoise", dash="dash"),
504
- ),
505
- row=1,
506
- col=2,
507
- )
508
-
509
- fig.update_xaxes(
510
- title_text="Count",
511
- title_font_size=font_size_legend,
512
- title_font_weight="bold",
513
- row=1,
514
- col=2,
515
- )
516
-
517
- # update layout
518
- fig.update_layout(barmode="overlay")
519
 
520
  if self.config["control"]["save_figure"] == "true":
521
  fig.write_image(
@@ -525,9 +509,9 @@ class CUSUM:
525
  "../../", self.config["path_output"]["path_figure"]
526
  )
527
  ),
528
- "fig_plot_1.png",
529
  ),
530
- scale=3,
531
  )
532
  print(
533
  "Created",
@@ -537,7 +521,7 @@ class CUSUM:
537
  "../../", self.config["path_output"]["path_figure"]
538
  )
539
  ),
540
- "fig_plot_1.png",
541
  ),
542
  )
543
 
@@ -555,14 +539,13 @@ class CUSUM:
555
  font_size_title = 20
556
  font_size_legend = 18
557
 
558
- # add subplots
559
  fig.add_trace(
560
  go.Scatter(
561
  x=list(range(len(self.S_hi))),
562
  y=self.S_hi / self.in_std,
563
  mode="lines",
564
  name=f"""Positive changes (S<sub>hi</sub>)""",
565
- marker=dict(color="greenyellow", size=10),
566
  )
567
  )
568
  fig.add_trace(
@@ -582,21 +565,7 @@ class CUSUM:
582
  y=[self.H / self.in_std, self.H / self.in_std],
583
  mode="lines",
584
  name="Threshold (h)",
585
- line=dict(color="skyblue", dash="dash"),
586
- )
587
- )
588
-
589
- # add vertical line
590
- fig.add_trace(
591
- go.Scatter(
592
- x=[self.pre_change_days, self.pre_change_days],
593
- y=[
594
- 0,
595
- np.max(self.S_lo / self.in_std),
596
- ],
597
- mode="lines",
598
- name="Change-point",
599
- line=dict(color="grey", dash="dash"),
600
  )
601
  )
602
 
@@ -606,7 +575,7 @@ class CUSUM:
606
  "font": {"size": font_size_title, "weight": "bold"},
607
  },
608
  xaxis_title={
609
- "text": "Length of observations",
610
  "font": {"size": font_size_legend, "weight": "bold"},
611
  },
612
  yaxis_title={
@@ -616,7 +585,28 @@ class CUSUM:
616
  xaxis=dict(dtick=20),
617
  )
618
 
619
- fig.update_layout(plot_bgcolor=self.config["color"]["blue_005"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
 
621
  fig.update_layout(
622
  legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
@@ -630,9 +620,9 @@ class CUSUM:
630
  "../../", self.config["path_output"]["path_figure"]
631
  )
632
  ),
633
- "fig_plot_2.png",
634
  ),
635
- scale=3,
636
  )
637
  print(
638
  "Created",
@@ -642,7 +632,7 @@ class CUSUM:
642
  "../../", self.config["path_output"]["path_figure"]
643
  )
644
  ),
645
- "fig_plot_2.png",
646
  ),
647
  )
648
 
 
60
 
61
  def set_init_stats(self, init_days: int) -> None:
62
  """
63
+ Use number of baseline observations to calculate in-control mean and standard deviation.
64
 
65
  Args:
66
+ init_days (int, optional): Number of baseline observations when observations are considered stable. Defaults to 30.
67
  """
68
  self.init_days = init_days
69
 
 
171
  normalized_ref_value (float, optional): Normalized reference value for detecting a unit standard deviation change in mean of the process. Defaults to 0.5.
172
  normalized_threshold (float, optional): Normalized threshold. Defaults to 4.
173
  """
174
+ self.pre_change_days = self.init_days # This is the number of baseline observations that we assume to be in-control - user enters or default = 30
175
 
176
  ref_val = normalized_ref_value
177
  control_limit = normalized_threshold
 
313
  fig.add_vrect(
314
  x0=0,
315
  x1=self.init_days,
316
+ annotation_text="Baseline observations",
317
  annotation_position="top right",
318
  fillcolor="palegreen",
319
  opacity=0.25,
 
326
  "font": {"size": font_size_title, "weight": "bold"},
327
  },
328
  xaxis_title={
329
+ "text": "Time",
330
  "font": {"size": font_size_legend, "weight": "bold"},
331
  },
332
  yaxis_title={
 
361
  y2 = self.data[self.pre_change_days : self.total_days]
362
  mean_y2 = np.mean(y2)
363
 
364
+ fig = go.Figure()
 
 
 
 
 
 
365
 
366
  font_size_title = 20
367
  font_size_legend = 18
 
376
  marker=dict(color="darkturquoise", size=10),
377
  opacity=0.4,
378
  ),
 
 
379
  )
380
  fig.add_trace(
381
  go.Scatter(
 
386
  marker=dict(color="coral", size=10),
387
  opacity=0.4,
388
  ),
 
 
389
  )
390
 
391
  # add horizontal lines
 
397
  name="In-control mean",
398
  line=dict(color="darkturquoise", dash="dash"),
399
  ),
 
 
400
  )
401
  fig.add_trace(
402
  go.Scatter(
 
406
  name="Out-of-control mean",
407
  line=dict(color="coral", dash="dash"),
408
  ),
 
 
409
  )
410
 
411
  # add vertical line
 
418
  line=dict(color="grey", dash="dash"),
419
  # textfont=dict(size=18)
420
  ),
 
 
421
  )
422
 
423
  fig.update_layout(
424
  title={
425
+ "text": "Pre- and post-change observations",
426
  "font": {"size": font_size_title, "weight": "bold"},
427
  },
428
  xaxis_title={
429
+ "text": "Time",
430
  "font": {"size": font_size_legend, "weight": "bold"},
431
  },
432
  yaxis_title={
 
442
  legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
443
  )
444
 
445
+ # # add histogram (like marginal histogram)
446
+ # nbinsx = 15 # 6
447
+
448
+ # # add subplots
449
+ # fig.add_trace(
450
+ # go.Histogram(
451
+ # y=self.data[: self.pre_change_days],
452
+ # nbinsy=nbinsx,
453
+ # # name=f"""Pre-change S<sub>p</sub>""",
454
+ # showlegend=False,
455
+ # marker=dict(color="mediumturquoise"),
456
+ # opacity=0.4,
457
+ # orientation="h",
458
+ # ),
459
+ # row=1,
460
+ # col=2,
461
+ # )
462
+
463
+ # fig.add_trace(
464
+ # go.Histogram(
465
+ # y=self.data[self.pre_change_days : self.total_days],
466
+ # nbinsy=nbinsx,
467
+ # # name=f"""Post-change S<sub>p</sub>""",
468
+ # showlegend=False,
469
+ # marker=dict(color="coral"),
470
+ # opacity=0.4,
471
+ # orientation="h",
472
+ # ),
473
+ # row=1,
474
+ # col=2,
475
+ # )
476
+
477
+ # fig.add_trace(
478
+ # go.Scatter(
479
+ # x=[0, 20], # [! y_max can should be used]
480
+ # y=[
481
+ # np.mean(self.data[: self.pre_change_days]),
482
+ # np.mean(self.data[: self.pre_change_days]),
483
+ # ],
484
+ # mode="lines",
485
+ # # name="Reference mean",
486
+ # showlegend=False,
487
+ # line=dict(color="mediumturquoise", dash="dash"),
488
+ # ),
489
+ # row=1,
490
+ # col=2,
491
+ # )
492
+
493
+ # fig.update_xaxes(
494
+ # title_text="Count",
495
+ # title_font_size=font_size_legend,
496
+ # title_font_weight="bold",
497
+ # row=1,
498
+ # col=2,
499
+ # )
500
+
501
+ # # update layout
502
+ # fig.update_layout(barmode="overlay")
503
 
504
  if self.config["control"]["save_figure"] == "true":
505
  fig.write_image(
 
509
  "../../", self.config["path_output"]["path_figure"]
510
  )
511
  ),
512
+ "fig_plot_data_distribution.png",
513
  ),
514
+ scale=6,
515
  )
516
  print(
517
  "Created",
 
521
  "../../", self.config["path_output"]["path_figure"]
522
  )
523
  ),
524
+ "fig_plot_data_distribution.png",
525
  ),
526
  )
527
 
 
539
  font_size_title = 20
540
  font_size_legend = 18
541
 
 
542
  fig.add_trace(
543
  go.Scatter(
544
  x=list(range(len(self.S_hi))),
545
  y=self.S_hi / self.in_std,
546
  mode="lines",
547
  name=f"""Positive changes (S<sub>hi</sub>)""",
548
+ marker=dict(color="rgb(0, 209, 209)", size=10),
549
  )
550
  )
551
  fig.add_trace(
 
565
  y=[self.H / self.in_std, self.H / self.in_std],
566
  mode="lines",
567
  name="Threshold (h)",
568
+ line=dict(color="rgb(250, 0, 125)", dash="dash"),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
  )
570
  )
571
 
 
575
  "font": {"size": font_size_title, "weight": "bold"},
576
  },
577
  xaxis_title={
578
+ "text": "Time",
579
  "font": {"size": font_size_legend, "weight": "bold"},
580
  },
581
  yaxis_title={
 
585
  xaxis=dict(dtick=20),
586
  )
587
 
588
+
589
+ fig.add_shape(
590
+ type="rect",
591
+ x0=0, x1=60,
592
+ y0=0, y1=1, # use relative values (0 to 1) for full y-range
593
+ xref="x", yref="paper", # "paper" for full plot height
594
+ fillcolor=self.config["color"]["blue_005"],
595
+ opacity=0.8,
596
+ layer="below",
597
+ line_width=0,
598
+ )
599
+
600
+ fig.add_shape(
601
+ type="rect",
602
+ x0=60, x1=len(self.S_lo), # x1=1 means extend to right edge of plot (paper coordinates)
603
+ y0=0, y1=1,
604
+ xref="x", yref="paper",
605
+ fillcolor="rgb(253, 243, 235)",
606
+ opacity=0.8,
607
+ layer="below",
608
+ line_width=0,
609
+ )
610
 
611
  fig.update_layout(
612
  legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
 
620
  "../../", self.config["path_output"]["path_figure"]
621
  )
622
  ),
623
+ "fig_plot_cusum_chart.png",
624
  ),
625
+ scale=6,
626
  )
627
  print(
628
  "Created",
 
632
  "../../", self.config["path_output"]["path_figure"]
633
  )
634
  ),
635
+ "fig_plot_cusum_chart.png",
636
  ),
637
  )
638
 
src/package/example_AIM_CU.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
src/package/utils.py CHANGED
@@ -59,7 +59,7 @@ def populate_summary_table_ARL0_k(summary_table_df_ARL0_k: pd.DataFrame, h) -> g
59
  table_great_table_ARL0_k.save(
60
  os.path.abspath(
61
  os.path.join(
62
- "../../", config["path_output"]["path_figure"], "table_ARL0_k.png"
63
  )
64
  ),
65
  scale=3,
@@ -69,7 +69,7 @@ def populate_summary_table_ARL0_k(summary_table_df_ARL0_k: pd.DataFrame, h) -> g
69
  "Created",
70
  os.path.abspath(
71
  os.path.join(
72
- "../../", config["path_output"]["path_figure"], "table_ARL0_k.png"
73
  )
74
  ),
75
  )
@@ -127,7 +127,7 @@ def populate_summary_table_ARL1_k(
127
  table_great_table_ARL1_k.save(
128
  os.path.abspath(
129
  os.path.join(
130
- "../../", config["path_output"]["path_figure"], "table_ARL1_k.png"
131
  )
132
  ),
133
  scale=3,
@@ -137,7 +137,7 @@ def populate_summary_table_ARL1_k(
137
  "Created",
138
  os.path.abspath(
139
  os.path.join(
140
- "../../", config["path_output"]["path_figure"], "table_ARL1_k.png"
141
  )
142
  ),
143
  )
 
59
  table_great_table_ARL0_k.save(
60
  os.path.abspath(
61
  os.path.join(
62
+ "../../", config["path_output"]["path_figure"], "fig_table_h_arl0_k.png"
63
  )
64
  ),
65
  scale=3,
 
69
  "Created",
70
  os.path.abspath(
71
  os.path.join(
72
+ "../../", config["path_output"]["path_figure"], "fig_table_h_arl0_k.png"
73
  )
74
  ),
75
  )
 
127
  table_great_table_ARL1_k.save(
128
  os.path.abspath(
129
  os.path.join(
130
+ "../../", config["path_output"]["path_figure"], "fig_table_h_k_arl1.png"
131
  )
132
  ),
133
  scale=3,
 
137
  "Created",
138
  os.path.abspath(
139
  os.path.join(
140
+ "../../", config["path_output"]["path_figure"], "fig_table_h_k_arl1.png"
141
  )
142
  ),
143
  )
tests/test.py CHANGED
@@ -23,6 +23,7 @@ class TestCUSUM(unittest.TestCase):
23
 
24
  def test_cusum(self):
25
  obj_cusum = CUSUM()
 
26
 
27
  path_file_config = os.path.abspath("../config/config.toml")
28
  with open(os.path.abspath(path_file_config), "rb") as file_config:
@@ -30,26 +31,28 @@ class TestCUSUM(unittest.TestCase):
30
 
31
  ref_value = 0.5
32
  normalized_threshold = 4
33
- pre_change_days = 60
34
 
35
  obj_cusum.df_metric = pd.read_csv(os.path.abspath("../config/spec-60-60.csv"))
36
  obj_cusum.data = obj_cusum.df_metric[obj_cusum.df_metric.columns[1]].to_numpy()
37
  obj_cusum.set_timeline(obj_cusum.data)
38
 
 
 
 
 
39
  obj_cusum.change_detection(
40
- pre_change_days=pre_change_days,
41
  normalized_ref_value=ref_value,
42
  normalized_threshold=normalized_threshold,
43
  )
44
 
45
  self.assertEqual(
46
- obj_cusum.S_lo[-1], 2.31, "Cumulative (negative) sum does not match."
47
  )
48
 
49
  def test_rpy2(self):
50
  arl_1 = get_ARL_1_h_mu1_k(h=4, k=0.2996, mu1=1.2)
51
 
52
- self.assertEqual(arl_1, 4.4304, "Package rpy2 is not working properly")
53
 
54
 
55
  if __name__ == "__main__":
 
23
 
24
  def test_cusum(self):
25
  obj_cusum = CUSUM()
26
+ # obj_cusum.initialize()
27
 
28
  path_file_config = os.path.abspath("../config/config.toml")
29
  with open(os.path.abspath(path_file_config), "rb") as file_config:
 
31
 
32
  ref_value = 0.5
33
  normalized_threshold = 4
 
34
 
35
  obj_cusum.df_metric = pd.read_csv(os.path.abspath("../config/spec-60-60.csv"))
36
  obj_cusum.data = obj_cusum.df_metric[obj_cusum.df_metric.columns[1]].to_numpy()
37
  obj_cusum.set_timeline(obj_cusum.data)
38
 
39
+ # Set initial days and get in-control mean and standard deviation
40
+ obj_cusum.set_init_stats(init_days=30)
41
+
42
+ # Detects a change in the process
43
  obj_cusum.change_detection(
 
44
  normalized_ref_value=ref_value,
45
  normalized_threshold=normalized_threshold,
46
  )
47
 
48
  self.assertEqual(
49
+ obj_cusum.S_lo[-1], 2.6, "Cumulative (negative) sum does not match."
50
  )
51
 
52
  def test_rpy2(self):
53
  arl_1 = get_ARL_1_h_mu1_k(h=4, k=0.2996, mu1=1.2)
54
 
55
+ self.assertEqual(arl_1, 4.43, "Package rpy2 is not working properly")
56
 
57
 
58
  if __name__ == "__main__":