Skip to content

Commit

Permalink
Merge branch 'Hotfix' into Stable
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanHurst committed Aug 20, 2020
2 parents 7da0dd3 + 328c9ee commit 4a4eee9
Show file tree
Hide file tree
Showing 21 changed files with 154 additions and 73 deletions.
2 changes: 1 addition & 1 deletion ADSM/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = '3.5.10.19' # SimulationMajor.SimulationMinor.UIRelease.UIMinor/Beta
__version__ = '3.5.10.21' # SimulationMajor.SimulationMinor.UIRelease.UIMinor/Beta
__year__ = '2019'
3 changes: 2 additions & 1 deletion ADSM/static/js/adsm.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ $(function(){
}
if($self.parent().find('button[type=submit]').hasClass('btn-danger')) {// MOST IMPORTANT: for deleting outputs on form submission
success_callback = function () {
window.location.reload()
//window.location.reload()
window.location.href = "/LoadingScreen/?loading_url=" + window.location.pathname;
}; //updates Navigation bar context
}
ajax_submit_complex_form_and_replaceWith(formAction, formData, $self, load_target, loading_message, success_callback);
Expand Down
4 changes: 2 additions & 2 deletions ADSMSettings/management/commands/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def run_scenarios(self):
self.log("\nAuto running %s..." % scenario)

open_scenario(None, scenario, wrap_target=True)
print("Starting Simulation run at %s" % djtimezone.now())
self.log("Starting Simulation run at %s" % djtimezone.now())
delete_all_outputs()
delete_supplemental_folder()
create_blank_unit_stats() # create UnitStats before we risk the simulation writing to them
Expand All @@ -234,7 +234,7 @@ def run_scenarios(self):
try:
max_iterations = OutputSettings.objects.all().first().iterations
except:
print("Unable to find OutputSettings! Scenario may not be complete or is corrupt. Skipping Scenario %s" % scenario)
self.log("Unable to find OutputSettings! Scenario may not be complete or is corrupt. Skipping Scenario %s" % scenario)
continue
else:
max_iterations = self.options['max_iterations']
Expand Down
64 changes: 33 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,49 +14,51 @@ There is a Beta and Release channel available for installation.
### Windows Release Channel
You can find the latest Release here: https://github.com/NAVADMC/ADSM/releases/latest

1. On the latest release page, download the "ADSM_Installer.exe".
1. Run the installer with admin privileges (ask your IT department for help if needed).
1. Follow the on screen prompts until "Choose Install Location".
1. Choose the folder in which to install ADSM. This is where the program will reside. It is generally best to put it in "Program Files".
1. Next, choose the User Workspace Folder for ADSM. If you are the only user of the computer, you can choose where to store your Workspace Folder (folder of your scenarios). Note that you must have Read/Write access to the chosen folder.
If ADSM is being installed on a shared computer and multiple users will use the program, leave this field BLANK so ADSM will find a suitable Workspace Folder that is writable and unique to each user.
1. Continue following the on screen prompts.
1. When installation is complete, find "ADSM.exe" (either a shortcut on your desktop or in the folder you installed ADSM) and run it.
1. On the latest release page, download the "ADSM_vx.x.x.x_windows.zip".
1. Extract the ADSM folder to any location your user has permissions.
1. If you are on a shared computer and multiple people are expected to use the ADSM installation, have an Admin on your computer place the ADSM folder in "Program Files" and created the desired program shortcuts.
1. Find "ADSM.exe" in the ADSM folder and run it.
1. When you launch ADSM for the first time, it will prompt you where the Workspace Folder should live.
1. In general, say "No" to the prompt and the Workspace will be created inside the ADSM folder.
1. If ADSM is being installed on a shared computer and multiple users will use the program, say "Yes" and select a common location that all users will have Read/Write permissions to (NOT in "Program Files").
1. After launching the application, a black Terminal window with white text will appear. You can leave this window alone; some debug messages may appear in it.
1. A Viewer window will then appear on top of the Terminal window. This is where you will interface with the ADSM program.
1. To properly exit ADSM, close the Viewer window. Doing so will automatically close the Terminal window after saving and shutting down all processes.

### Debian Linux Release Channel
NOTE: v3.3.7.0 was the last version that had a Linux Build compiled. For now, Linux users should follow instructions for Installing ADSM For Development.

You can find the latest Release here: https://github.com/NAVADMC/ADSM/releases/latest

An installation process does not yet exist for Linux, so it is best for each user on a machine to download their own local copy of the program.
### Notes on the ADSM Workspace Folder
If you selected "No" to specifying a Workspace location and the Workspace was automatically created in the ADSM folder, your installation is considered "Portable".
This means that you can move the entire ADSM folder from one computer to another and have all your data and settings move around with it.

1. On the latest release page, download the "ADSM.tar.gz".
1. Extract the package into the folder in which you want ADSM to be installed. It is best to do this somewhere in your User space.
1. Run the "ADSM" executable in the extracted folder.
1. After launching the application, a Terminal will appear. You can leave this Terminal alone; some debug messages may appear in it.
1. A Viewer window will then appear on top of the Terminal window. This is where you will interface with the ADSM program.
1. To properly exit ADSM, close the Viewer window. Doing so will automatically close the Terminal after saving and shutting down all processes.
It is NOT suggested to attempt to run the ADSM program from a portable drive as there may be performance issues.
If you put your installation on a portable drive to do work on another computer, copy the installation onto the new computer's internal Hard Drive before doing your work.

You can change where ADSM looks for the Workspace Folder at any time by opening the Scenario Browser in the right nav panel of the program and clicking "(change)" next to the Current Workspace path.
Doing this will prompt you to close the program and launch again going through the initial setup as described during the installation process.

### Windows And Linux Beta Channel
You can find the latest Pre-release on the Releases page: https://github.com/NAVADMC/ADSM/releases
NOTE: v3.3.7.0 was the last version that had a Linux Build compiled. For now, Linux users should follow instructions for Installing ADSM For Development.

Beta builds do not come with an installer, so it is best for each user on a machine to download their own local copy of the program.
You can find the latest Pre-release on the Releases page: https://github.com/NAVADMC/ADSM/releases

**WARNING:** If you have a Release installation on your computer, the Beta install MAY **overwrite your scenarios** from the Release version if you didn't specify a custom Workspace directory during Release install.
If ADSM is selecting the Workspace directory automatically both the Release and Beta channel will select the same folder.
**WARNING:** If you have a Release installation on your computer, the Beta install MAY **overwrite your scenarios** from the Release version if you point both installations to the same Workspace Folder.
If ADSM is automatically putting the Workspace Folder in the ADSM folder, there will be no conflict.

1. On the latest pre-release page, download either "ADSM_vx.x.x.x-beta_windows.zip" or "ADSM_vx.x.x.x-beta_linux.tar.gz"
1. Extract the package into the folder in which you want ADSM Beta to be installed. It is best to do this somewhere in your User space (a directory your user owns).
1. If you need to specify a different Workspace Folder to avoid a conflict with a Production Release, follow these steps.
1. In your ADSM Beta folder, create a file called "workspace.ini".
1. Using your favorite text editor, add one of the following lines:
1. Windows: `WORKSPACE_PATH = 'DRIVE:\\desired\\path\\to\ADSM Beta Workspace'`
1. Linux: `WORKSPACE_PATH = '/desired/path/to/ADSM Beta Workspace'`
1. Run the "ADSM_Beta.exe" or "ADSM_Beta" executable in the extracted folder.
1. After launching the application, a Terminal will appear. You can leave this Terminal alone; runtime and debug messages will appear in it.
1. A Viewer window will then appear on top of the Terminal window. This is where you will interface with the ADSM Beta program.
1. To properly exit ADSM Beta, close the Viewer window. Doing so will automatically close the Terminal after saving and shutting down all processes.
1. Extract the ADSM_Beta folder to any location your user has permissions.
1. If you are on a shared computer and multiple people are expected to use the ADSM_Beta installation, have an Admin on your computer place the ADSM_Beta folder in "Program Files" and created the desired program shortcuts.
1. Find "ADSM_Beta.exe" in the ADSM_Beta folder and run it.
1. When you launch ADSM_Beta for the first time, it will prompt you where the Workspace Folder should live.
1. In general, say "No" to the prompt and the Workspace will be created inside the ADSM_Beta folder.
1. If ADSM_Beta is being installed on a shared computer and multiple users will use the program, say "Yes" and select a common location that all users will have Read/Write permissions to (NOT in "Program Files").
1. Make sure to pick a location that doesn't conflict a Workspace Folder from a non beta installation of ADSM.
1. After launching the application, a black Terminal window with white text will appear. You can leave this window alone; some debug messages may appear in it.
1. A Viewer window will then appear on top of the Terminal window. This is where you will interface with the ADSM_Beta program.
1. To properly exit ADSM_Beta, close the Viewer window. Doing so will automatically close the Terminal window after saving and shutting down all processes.

### Installing ADSM On A Server (Cloud Hosting)
**NOTE:** ADSM was developed with the intention to move it towards a Cloud Hosted environment. It is setup to run as a webserver already. HOWEVER, it is not multi-user friendly yet so should not be setup in this way except for demo purposes.
Expand Down Expand Up @@ -369,9 +371,9 @@ The ADSM releases are:
Project Members:

* Project Owner - Missy Schoenbaum, USDA:APHIS:VS:CEAH Modeling Team contact [email protected]
* ADSM Technical Lead - Josiah Seaman
* ADSM Technical Lead - Josiah Seaman, Newline Technical Innovations, LLC
* Simulation Creator / Maintainer - Neil Harvey
* Dev Ops - Bryan Hurst
* Dev Ops - Bryan Hurst, Newline Technical Innovations, LLC
* Project Management - Alex Pyle & Kurt Tometich, USDA Office of the CIO
* USDA Subject Matter Experts - Kelly Patyk, Amy Delgado, Columb Rigney, Kim Forde-Folle, Ann Seitzinger
* University of Minnesota Center for Food Protection Subject Matter Expert Tim Boyer
Expand Down
19 changes: 9 additions & 10 deletions Results/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@

from unittest import skip


# @skip("Skipping Simulation Tests") # uncomment this line to skip these test cases, this will drastically increase the speed of testing
class SimulationTest(TransactionTestCase):
multi_db = True

@classmethod
def setUpClass(cls):
source_db = os.path.join(settings.BASE_DIR, 'ScenarioCreator', 'tests', 'population_fixtures', 'Roundtrip.db')
cls.destination_db = workspace_path('Roundtrip_test.db')
cls.destination_db = workspace_path('Roundtrip_test/Roundtrip_test.db')
os.makedirs(workspace_path('Roundtrip_test'))
shutil.copy(source_db, cls.destination_db)
cls.scenario_directory = workspace_path('Roundtrip_test')

@classmethod
def tearDownClass(cls):
os.remove(cls.destination_db)
shutil.rmtree(cls.scenario_directory, ignore_errors=True)

def setUp(self):
self.client.get('/app/OpenScenario/Roundtrip_test.db/')
Expand All @@ -39,7 +40,8 @@ def setUp(self):
close_old_connections()

def tearDown(self):
shutil.rmtree(self.scenario_directory, ignore_errors=True)
pass
# shutil.rmtree(self.scenario_directory, ignore_errors=True)

# @skip("Waiting on updated adsm_simulation")
def test_multiple_threads(self):
Expand Down Expand Up @@ -69,15 +71,15 @@ def test_supplemental_output_created(self):
settings.save_daily_unit_states = True
settings.save()
close_old_connections()
output_file = os.path.join(self.scenario_directory, 'states_1.csv')
output_file = os.path.join(self.scenario_directory, 'Supplemental Output Files', 'states_1.csv')

sim = Simulation(1, testing=True)
sim.start()
sim.join()

self.assertTrue(os.access(output_file, os.F_OK))

# @skip("Waiting on updated adsm_simulation")
@skip("Zipped map outputs are no longer being created (#1006)")
def test_map_zip_with_output(self):
settings = OutputSettings.objects.first()
settings.save_daily_unit_states = True
Expand All @@ -96,7 +98,7 @@ def test_map_zip_with_output(self):
with zipfile.ZipFile(file_name, 'r') as zf:
self.assertListEqual(zf.namelist(), os.listdir(folder_name))

# @skip("Waiting on updated adsm_simulation")
@skip("Zipped map outputs are no longer being created (#1006)")
def test_map_zip_no_output(self):
settings = OutputSettings.objects.first()
settings.save_map_output = False
Expand Down Expand Up @@ -305,9 +307,6 @@ def test_parser_only_outputs_needed_objects(self):
class ResultsVersionTestCase(TestCase):
multi_db = True

def test_model_is_singleton(self):
self.assertIsInstance(ResultsVersion.objects, SingletonManager)

def test_save(self):
result = ResultsVersion()
result.id = 2
Expand Down
11 changes: 7 additions & 4 deletions Results/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ def get_simulation_controllers():
for record in records:
for process in psutil.process_iter():
if process.pid == record.pid:
if 'python' not in process.name().lower() and 'adsm' not in process.name().lower():
record.delete() # stale process record where the pid was reused
else: # process call python
results.append(process)
try:
if 'python' not in process.name().lower() and 'adsm' not in process.name().lower():
record.delete() # stale process record where the pid was reused
else: # process call python
results.append(process)
except psutil.AccessDenied as e:
continue
return results


Expand Down
16 changes: 16 additions & 0 deletions ScenarioCreator/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def export_relational_functions(functions, points):
:param points: all of the relational point objects, these must be matched to functions before being exported
:return: None
'''

# stamp into cmd (#1016)
print("Starting REL function export...")

# open and erase or create the export file
try:
os.makedirs(workspace_path("\\Exports\\Exported Functions\\"))
Expand All @@ -30,6 +34,10 @@ def export_relational_functions(functions, points):
csvwriter.writerow(next_func)
# close the file to save and avoid corruption
file.close()

# stamp out of cmd (#1016)
print("Function export complete.")

return


Expand All @@ -40,6 +48,10 @@ def export_pdfs(functions):
:param functions: The existing pdfs
:return: None
'''

# stamp into cmd (#1016)
print("Starting PDF export...")

# Open and erase or create the output file
try:
os.makedirs(workspace_path("\\Exports\\Exported Functions\\"))
Expand All @@ -53,4 +65,8 @@ def export_pdfs(functions):
csvwriter.writerow([str(getattr(function, key)) for key in ProbabilityDensityFunction.export_fields])
# close the file to save and avoid corruption
file.close()

# stamp out of cmd (#1016)
print("Function export complete.")

return
2 changes: 1 addition & 1 deletion ScenarioCreator/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class ProbabilityDensityFunctionForm(BaseForm):
class Meta(object):
model = ProbabilityDensityFunction
exclude = []
widgets = {'graph': PiecewiseSelect()}
widgets = {'graph': SelectExisting()}

def clean(self):
cleaned_data = super(ProbabilityDensityFunctionForm, self).clean()
Expand Down
30 changes: 21 additions & 9 deletions ScenarioCreator/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@


def import_relational_functions(existing_functions):
'''
"""
Import the relational functions
Relational functions are saved with their points, however the database stores the functions and the points
seperatly. We need to build a funciton for each line of each file, as well as an unknown number of points that
also need to be linked to the correct funciton.
separately. We need to build a function for each line of each file, as well as an unknown number of points that
also need to be linked to the correct function.
:param existing_functions: list of existing relational functions, this is used to avoid duplicate names
:return: None
'''
"""

# stamp into cmd (#1016)
print("Starting REL function import...")

# get a list of all file names delimited by "REL_", are .csv, and do not have the current scenario's name
file_names = [file for file in listdir(workspace_path(scenario_filename() + "\\Imports\\")) if
Expand Down Expand Up @@ -81,23 +83,29 @@ def import_relational_functions(existing_functions):
new_points.save()
# close the file to avoid corruption
file.close()

# stamp out of cmd (#1016)
print("Function import complete.")
return


def import_pdfs(existing_functions):
'''
"""
Import the pdfs
Each pdf needs to be read in from the file and built in an object for the database
:param existing_functions: list of existing functions, used to avoid creating duplicate function names
:return: None
'''
"""

# stamp into cmd (#1016)
print("Starting PDF import...")

# get a list of all file names delimited by "PDF_", are .csv, and do not have the current scenario's name
file_names = [file for file in listdir(workspace_path(scenario_filename() + "\\Imports\\")) if
str(file).startswith("PDF_") and
str(file).endswith(".csv")]
str(file).startswith("PDF_") and
str(file).endswith(".csv")]
# get a list of the existing pdf's names.
existing_pdf_names = [pdf.name for pdf in existing_functions]
# list of fields that need to be imported
Expand Down Expand Up @@ -132,4 +140,8 @@ def import_pdfs(existing_functions):
new_pdf.save()
# close the file to avoid corruption.
file.close()

# stamp out of cmd (#1016)
print("Function import complete.")

return
4 changes: 2 additions & 2 deletions ScenarioCreator/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,6 @@ def validate(self):
],
'use_vaccination': ['vaccinate_detected_units',
'minimum_time_between_vaccinations',
'days_to_immunity',
'vaccine_immune_period',
],
'use_cost_accounting': ['cost_of_destruction_appraisal_per_unit',
'cost_of_destruction_cleaning_per_unit',
Expand Down Expand Up @@ -644,6 +642,8 @@ def __str__(self):
return self.name

def tab_is_valid(self, use_tab_name, fields=None):
if use_tab_name is "use_vaccination":
return True
if fields is None:
fields = protocol_substructure[use_tab_name]
for field in fields:
Expand Down
Loading

0 comments on commit 4a4eee9

Please sign in to comment.