From d51b4967df13de045c237218bd891750132ce5ea Mon Sep 17 00:00:00 2001 From: Joe Allen Date: Thu, 10 Oct 2024 13:46:00 -0500 Subject: [PATCH 1/5] Hotfix branch (#71) --- Makefile | 6 +++--- README.md | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 04e2ba6..77b56a7 100644 --- a/Makefile +++ b/Makefile @@ -5,12 +5,12 @@ help: ## Display this help screen .PHONY: build build: ## build dev - docker compose -f docker-compose-dev.yml build + docker compose -f docker-compose.yml build .PHONY: start start: ## start dev environment where client code changes will be automatically updated on running client - docker compose -f docker-compose-dev.yml up + docker compose -f docker-compose.yml up -d --build .PHONY: stop stop: ## stop dev - docker compose -f docker-compose-dev.yml stop + docker compose -f docker-compose.yml stop diff --git a/README.md b/README.md index 280ebd5..3ecb3c0 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,24 @@ ## Getting Started -#### Build the development environment +#### Build the production environment ```bash make build ``` -#### Start the development environment +#### Start the production environment ```bash make start ``` Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + + +#### Stop the production environment + +```bash +make stop +``` + From 6d309eaf87c72493c5d6bba73fcfda38f8c00ac1 Mon Sep 17 00:00:00 2001 From: Joseph Hendrix <80018977+joeleehen@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:16:25 -0500 Subject: [PATCH 2/5] Hot fix userguide (#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Frontend UI updates (#9) * Updated banner name and homeview panel layering bug * Updated ChartView layout to no longer have false right panel * Updated react grid layout * Updated dependency versions * Created PlayPauseButton as a separate component from the timeline-slider and moved it to the left panel * Cleaned up redundant classNames for timeline-slider after PlayPauseButton removal * Simplified classNames for timeline-slider * Consolidated .css references to modal and button elements * Moved left panel features and leaflet features to their own .css files * Fixed layering issues present when popup menus are active * Edited z-index for dropdown container * Improved loading so grid layout adheres to user settings as days progress on timeline * Container integration, reorg into client folder, and work on SetParameters button (#3) * reorg for django and modifying set parameters button * moved files around * Configured django backend and added some docker stuff (#4) * added dockerfile for django and updated docker compose * configured django backend * Input integration - updating buttons in left panel (#5) * Updated SetManually to capture all parameters Verified that R0, beta_scale, tau, kappa, gamma, chi, rho, nu_high, vaccine_wastage_factor, antiviral_effectiveness, antiviral_wastage_factor are all saved in json file * Add Initial Cases generates a json file in format needed for the INPUT.json file - Added texasMapping.json, which captures county name and number Next steps: merge parameters & initial cases to input.json files * Ability to save parameters and initial cases to same INPUT.json file -Note: Case Fatality Rate is not included To fix: make 3 separate columns and have the INPUT.json file save to local directory * Add Initial Cases with table format - Commented out Risk Groups - Added slight gap between buttons and button width to span the left panel * Adjusted layout for Home View - Map and Line Chart in the middle section - Table on the right - Play button and Timeline slider on the footer To add: Parameters on the left panel * Removed unnecessary components --------- Co-authored-by: gladyschenyx <98440939+gladyschenyx@users.noreply.github.com> * Axios integration (#6) * Renamed react folder to frontend * Connecting front and backend * Updated size of buttons, font sizes, size of deceased line chart * Front-end updates - Parameters list on the left panel reflects "Set Manually" parameters - Initial Cases now able to add/remove cases - Saved Initial Cases to be moved to left panel (under parameters) - Aesthetic fixes (Font sizes, buttons, search icons, size of chart/maps) * Modal closes whenever save button is clicked in Set Parameters --------- Co-authored-by: LenaEDS <68430483+LenaEDS@users.noreply.github.com> Co-authored-by: Lena Duplechin Seymour Co-authored-by: Joe Allen * updated makefile and readme to reflect production deployment (#70) * Updated user guide and fixed tool-tip * Removed version to resolve warning WARN[0000] /Users/…/Downloads/PandemicExerciseTool-main/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? make: *** [start] Error 1 * added images for userguide * Removed version from docker compose yml to avoid warning WARN[0000] /Users/…/Downloads/PandemicExerciseTool-main/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? make: *** [start] Error 1 * Ensure html compatibility for User Guide text * User Guide Updates * bugfix: accordion buttons no longer extend horizontally when opened --------- Co-authored-by: gladyschenyx <98440939+gladyschenyx@users.noreply.github.com> Co-authored-by: LenaEDS <68430483+LenaEDS@users.noreply.github.com> Co-authored-by: Lena Duplechin Seymour Co-authored-by: Joe Allen Co-authored-by: Joseph Hendrix Co-authored-by: Joseph Hendrix --- docker-compose-dev.yml | 2 - docker-compose.yml | 2 - frontend/src/components/Legend.css | 2 +- frontend/src/components/UserGuideView.css | 73 ++++++- frontend/src/components/UserGuideView.js | 202 ++++++++++++++++-- .../images/userGuide-InitialCases1.png | Bin 0 -> 53028 bytes .../images/userGuide-InitialCases2.png | Bin 0 -> 36918 bytes .../images/userGuide-InitialCases3.png | Bin 0 -> 36050 bytes .../images/userGuide-InitialCases4.png | Bin 0 -> 107660 bytes .../src/components/images/userGuide-NPIs1.png | Bin 0 -> 18824 bytes .../src/components/images/userGuide-NPIs2.png | Bin 0 -> 48672 bytes .../src/components/images/userGuide-NPIs3.png | Bin 0 -> 55817 bytes .../src/components/images/userGuide-NPIs4.png | Bin 0 -> 17352 bytes .../images/userGuide-countToggle.png | Bin 0 -> 263316 bytes .../images/userGuide-countySearch.png | Bin 0 -> 181355 bytes .../components/images/userGuide-lineChart.png | Bin 0 -> 291108 bytes .../components/images/userGuide-onHover.png | Bin 0 -> 272033 bytes .../images/userGuide-parameters1.png | Bin 0 -> 44635 bytes .../images/userGuide-parameters2.png | Bin 0 -> 58804 bytes .../src/components/images/userGuide-pause.png | Bin 0 -> 66872 bytes .../images/userGuide-playScenario.png | Bin 0 -> 517869 bytes .../images/userGuide-presetSave.png | Bin 0 -> 92720 bytes .../images/userGuide-resetButton.png | Bin 0 -> 9980 bytes .../images/userGuide-setScenario.png | Bin 0 -> 59315 bytes .../images/userGuide-summaryPanel.png | Bin 0 -> 50201 bytes .../images/userGuide-timelineSlide.png | Bin 0 -> 289446 bytes .../images/userGuide-toggleCompartments.png | Bin 0 -> 280829 bytes 27 files changed, 256 insertions(+), 25 deletions(-) create mode 100644 frontend/src/components/images/userGuide-InitialCases1.png create mode 100644 frontend/src/components/images/userGuide-InitialCases2.png create mode 100644 frontend/src/components/images/userGuide-InitialCases3.png create mode 100644 frontend/src/components/images/userGuide-InitialCases4.png create mode 100644 frontend/src/components/images/userGuide-NPIs1.png create mode 100644 frontend/src/components/images/userGuide-NPIs2.png create mode 100644 frontend/src/components/images/userGuide-NPIs3.png create mode 100644 frontend/src/components/images/userGuide-NPIs4.png create mode 100644 frontend/src/components/images/userGuide-countToggle.png create mode 100644 frontend/src/components/images/userGuide-countySearch.png create mode 100644 frontend/src/components/images/userGuide-lineChart.png create mode 100644 frontend/src/components/images/userGuide-onHover.png create mode 100644 frontend/src/components/images/userGuide-parameters1.png create mode 100644 frontend/src/components/images/userGuide-parameters2.png create mode 100644 frontend/src/components/images/userGuide-pause.png create mode 100644 frontend/src/components/images/userGuide-playScenario.png create mode 100644 frontend/src/components/images/userGuide-presetSave.png create mode 100644 frontend/src/components/images/userGuide-resetButton.png create mode 100644 frontend/src/components/images/userGuide-setScenario.png create mode 100644 frontend/src/components/images/userGuide-summaryPanel.png create mode 100644 frontend/src/components/images/userGuide-timelineSlide.png create mode 100644 frontend/src/components/images/userGuide-toggleCompartments.png diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index cef0e0b..89d992c 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,6 +1,4 @@ --- -version: "3" - services: mongo-db: image: mongo:8.0-rc diff --git a/docker-compose.yml b/docker-compose.yml index 2596f31..4a4399b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,4 @@ --- -version: "3" - services: mongo-db: image: mongo:8.0-rc diff --git a/frontend/src/components/Legend.css b/frontend/src/components/Legend.css index 1bf81bd..7accfff 100644 --- a/frontend/src/components/Legend.css +++ b/frontend/src/components/Legend.css @@ -75,7 +75,7 @@ } .county-tooltip { - width: 200px; + width: max-content; font-size: large; background-color: white; color: black; diff --git a/frontend/src/components/UserGuideView.css b/frontend/src/components/UserGuideView.css index 0da4e8d..c5150ec 100644 --- a/frontend/src/components/UserGuideView.css +++ b/frontend/src/components/UserGuideView.css @@ -6,14 +6,61 @@ /* box-sizing: inherit; */ } +.li { + margin-left: 1em; +} + +.accordion { + background: #f1f1f1; +} + +.accordion-toggle { + height: 0px; + font-size: 18px; + opacity: 0; + transition: + opacity 0.3s ease-in-out, + height 0.3s 0.3s ease-in-out; + color: #333; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} + +.accordion-visible { + background: #dfa53d; + width: 100%; + color: #fff; + cursor: pointer; + border: 1px solid #dfa53d; + display: flex; + justify-content: space-between; + align-items: center; + padding: 7px 15px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + margin-bottom: 1em; +} + +.accordion-visible span { + padding: 15px 0; + font-size: 20px; +} + +.animated { + opacity: 1; + transition: + height 0.3s ease-in-out, + opacity 0.3s 0.3s ease-in-out; +} + .user-guide-view { font-family: Arial, sans-serif; margin: 5em; - max-width: 90vw; + max-width: 70vw; } .text { - margin-top: 3em; + /*margin-top: 3em;*/ margin-bottom: 30px; } @@ -47,10 +94,25 @@ text-decoration: underline; } +.instructions img { + display: block; + margin-left: auto; + margin-right: auto; + width: 30%; + margin-bottom: 1em; + border-radius: 4px; +} + .table-section { margin-top: 30px; } +.text h3 { + font-size: 2em; + margin-bottom: 15px; + text-align: left; +} + .table-section h3 { font-size: 2em; margin-bottom: 15px; @@ -68,6 +130,7 @@ padding: 12px; text-align: left; font-size: 1.2em; + text-wrap: balance; } .guide-table th { @@ -93,11 +156,11 @@ font-size: 1.5em; /* Match the font size of the paragraph text */ line-height: 1.6; list-style-type: disc; /* Standard bullet points */ - padding-left: 20px; /* Indent the list */ + padding-left: 2em; /* Indent the list */ margin-top: 0; /* Remove top margin if needed */ + margin-bottom: 1.6; } - .code-section { margin-top: 30px; } @@ -181,4 +244,4 @@ font-family: monospace; white-space: pre-wrap; margin-bottom: 5px; - } \ No newline at end of file + } diff --git a/frontend/src/components/UserGuideView.js b/frontend/src/components/UserGuideView.js index 96e5342..18ef9b8 100644 --- a/frontend/src/components/UserGuideView.js +++ b/frontend/src/components/UserGuideView.js @@ -1,4 +1,5 @@ import React from 'react'; +import { useState, useEffect, useRef } from "react"; import './UserGuideView.css'; // Ensure this CSS file is updated @@ -119,20 +120,80 @@ const appendixData = [ ]; const UserGuideView = () => { + const [toggleModelInfo, setToggleModelInfo] = useState(false); + const [toggleInstructions, setToggleInstructions] = useState(false); + const [heightInfo, setHeightInfo] = useState(); + const [heightInstructions, setHeightInstructions] = useState(); + + // const refHeightInfo = useRef(); + // useEffect(() => { + // setHeightInfo(`${refHeightInfo.current.scrollHeight}px`) + // }, []) + // + // const refHeightInstructions = useRef(); + // useEffect(() => { + // setHeightInstructions(`${refHeightInstructions.current.scrollHeight}px`) + // }, []) + + const modelInfoToggler = () => { + setToggleModelInfo(!toggleModelInfo); + }; + + const instructionsToggler = () => { + setToggleInstructions(!toggleInstructions); + }; + + const AccordionItem = ({ title, children }) => { + const [isOpen, setIsOpen] = useState(false); + + const toggleAccordion = () => { + setIsOpen(!isOpen); + }; + + return ( +
+ + {isOpen && ( +
+ {children} +
+ )} +
+ ); + }; + + // styles for accordion and its children + const styles = { + accordionButton: { + width: '100%', + padding: '25px 16px', + fontSize: 'larger', + fontWeight: 'bold', + borderRadius: '4px', + textAlign: 'left', + background: '#f7b13c', + border: 'none', + cursor: 'pointer', + outline: 'none', + }, + accordionContent: { + padding: '10px', + background: 'f9f9f9', + border: '1px solid #ccc', + borderRadius: '4px', + }, + }; + return (
-

Pandemic Exercise Simulator

-

Updated as of 8/6/2024

+

Interactive Outbreak Simulator

+

Updated as of 10/11/2024

https://github.com/TACC/PandemicExerciseSimulator -

Overview: This is a Python implementation of a Pandemic Exercise Simulator using a SEATIRD compartment model and binomial travel model. The simulator was implemented in such a way that it is modular, and can use alternative disease models, travel models, and eventually interventions (e.g. PHAs, antivirals, vaccines).

-

- This simulator can be run using the command line interface. It will also be the main calculation engine behind the graphical web app, hosted here (in development):

- - https://github.com/TACC/PandemicExerciseTool -

Needed: This tool is still in development and will benefit from testing and expert review. In particular, we need: @@ -142,6 +203,117 @@ const UserGuideView = () => {

  • Review of the Binomial Travel Model implementation.
  • A range of example input data and parameters, as well as expected outputs for testing and verification.
  • +
    +
    + + + +

    + + + +
    + {/* */} + {/* */} +
    + ) +}; + +const Instructions = () => { + return ( +
    +
    +

    Set the scenario with the 'Set Scenario' button in the top-left corner of the screen

    + Setting the Scenario +

    Select 'Disease Parameters' from the dropdown menu to specify starting conditions for the outbreak

    +
      +
    • R0: average number of secondary infections in a susceptible population
    • +
    • Latency period (days): average number of days spent asymptomatic immediately after infection
    • +
    • Asymptomatic period (days): average number of days spent infectious, but not yet symptomatic
    • +
    • Symptomatic period (days): average number of days spent symptomatic and infectious
    • +
    • Asymptomatic rate (proportion): proportion of infections that never developed symptoms
    • +
    • Infection fatality rate (proportion): proportion of infections that lead to death
    • +
    + Selecting Parameters + Inputting Parameters +

    Load a preset scenario from the catalog and hit the 'Save' button

    + Saving Parameters +

    Select 'Initial Cases' from the dropdown menu to specify initial infections

    + Saving Parameters +

    Click the '+ Add Cases' button to add initial cases for a particular county

    + Saving Parameters +

    For instance, enter the following entries:

    +
      +
    • Location: Travis
    • +
    • Number of Cases: 100
    • +
    • Age Group: 0-4 years
    • +
    + Adding Initial Cases +
      +
    • Location: Harris
    • +
    • Number of Cases: 100
    • +
    • Age Group: 0-4 years
    • +
    + Additional Initial Cases +

    After adding cases, click 'Save and Close' to submit initial cases

    +

    Saved scenario parameters and initial cases will be summarized in the left-hand panel

    + {/* Summary Panel */} +

    Click the 'Play' button in the bottom-left corner to run the simulation

    + Running the Simulation +

    Hovering over the map will display the infections for specific counties

    + Hovering over Counties +

    The infection map can be toggled to display the number of infected individuals per county

    + Toggling Absolute Counts +

    Hover over the line chart at the bottom of the screen to see total statewide compartment counts

    + Line Chart +

    Clicking on a compartment in the legend will toggle that compartment on or off in the line chart

    + Toggling Compartments +

    + The table on the right-hand side of the screen can be sorted alphabetically by county or in + ascending/descending order based on infections or deaths +

    +

    + Use the search bar above the table to search for specific counties +

    + Searching for Counties +

    The 'Pause' button will halt the simulation

    + Pausing the Simulation +

    Once the simulation is paused, slide the timeline back and forth to navigate to specific days

    + Scrubbing the Timeline +

    + To change disease parameters, edit initial cases, or include non-pharmaceutical interventions, the simulation + must first be reset. Clicking the 'Reset Simulation' button in the left-hand pane will reset the simulator +

    + Reset Button +

    Interventions are added using the '+ Add Interventions' button beneath the 'Set Scenario' button

    + Setting the Scenario +

    + Select 'Non-Pharmaceutical' from the dropdown menu to add non-pharmaceutical interventions, or NPIs +

    + Selecting NPIs +

    Click the 'Add New NPI' button to confirm NPI parameters

    +
      +
    • NPI start (simulation day): day of simulation on which the NPI is initiated
    • +
    • NPI duration (days): the number of days the NPI is active
    • +
    • + NPI effectiveness (proportion): age-specific reduction in susceptibility + (0 = no protection; 1 = complete protection) +
    • +
    + Selecting NPIs +

    After adding, click 'Save' to submit NPIs to the simulator

    + Saving NPIs +

    Clicking 'Interventions' in the left-hand summary pane will display intervention information

    + Summarized NPIs +
    +
    + ) +} + +const ModelInfo = () => { + return ( +
    +

    Data Description

    This simulator expects the following inputs to be present:

    @@ -329,7 +501,7 @@ const UserGuideView = () => {

    Disease Model

    The current implementation, Stochastic SEATIRD, was adapted from a previous code base. The main entrypoint to this disease model is a method called simulate(), which is called for each day, for each node, from src/simulator.py. This method models the progression of individuals through different stages of disease, including susceptible, exposed, asymptomatic, treatable, infectious, recovered, and deceased. The output of the method is the updated state of the population, including the number of individuals in each disease stage for each age group, risk group, and vaccination status, at the end of the simulation period.

    -

    The main logic of the method is to work through an “event queue” associated with each node. Events are either transitions from one compartment to another (e.g. I => R), or contacts. The event queue is initialized by the user-input initial infected, then it continues to take on new events through the course of simulation.

    +

    The main logic of the method is to work through an “event queue” associated with each node. Events are either transitions from one compartment to another (e.g. I => R), or contacts. The event queue is initialized by the user-input initial infected, then it continues to take on new events through the course of simulation.

    A plain text description of the workflow is as follows: