/WRF-WindNinja-FarsiteScript

temporary fork. Not for use

Primary LanguageC++

#################  Project General Overview  #################

This project is still under work, but at least at this point the code can run with simple inputs on Ubuntu 16.04 and Ubuntu 18.04 machines and Aeolus. The WRF-WindNinja-FarsiteScript code is designed to run Farsite and WindNinja automatically using a single input file and a number of inputs, including WRF weather output netcdf files, a landscape .lcp file, and ignition shape files. They haven't been linked in yet, but the optional barrier files used in Farsite could also be provided.

The end goal for the AIRPACT-Fire project was for the user to provide WRF files, provide the .lcp file or have it automatically download, provide the ignition shape files or ignition point locations or downloaded GeoMAC fire perimeters for use as ignitions. While WindNinja can run in many more modes than just providing WRF files, the WRF-WindNinja-FarsiteScript currently limits the WindNinja functionality to only be the WRF weather file inputs. This functionality may be added in at some time, but hasn't been focused on yet, since the focus has been on the needs of the AIRPACT-Fire project. To add this functionality, in theory would just be doing little more work than playing around with the inputs to the WRF-WindNinja-FarsiteScript, but in practice might mean much more work, as it would basically mean having each and every WindNinja input repeated as inputs to the WRF-WindNinja-FarsiteScript.

The WRF-WindNinja-FarsiteScript code also runs Farsite in a more limited mode as well. Basically the number of inputs that are required to this script are less than those required by WindNinja and Farsite, as the other inputs are chosen automatically by the WRF-WindNinja-Farsite script. The inputs to this script should be decently documented, and there is an example in the repo that shows the inputs at each stage of the process. WindNinja also has nicely documented inputs. Farsite's inputs are not well documented inside Farsite itself, I spent two months trying to piece together what they were at the start of the project, and I never quite got to a good clear way of explaining them. But you should be able to see what inputs for Farsite are expected from the user vs the actual inputs for Farsite used by the script by comparing inputs at each stage of the process.

One last thing, Loren Atwood is still pretty much the only one working on this script, but since the end of summer 2018, the work to advance this script has been limited to 5 hours every two weeks. In the summer of summer 2019, Loren had a small window to do more work, but after June 5th, Loren Atwood isn't planning on working much on the script till after May 2020 when he graduates from grad school. This means that for users of the script that want to use the script outside the scope of the AIRPACT-Fire project, if the script is still far away from what you need, it may be difficult to get the actual developers of the script to make changes for you, instead you may just be given information and ideas that you can work on for yourself.



#################  Planned General Overview of Code Flow in WRF-WindNinja-FarsiteScript  #################

1) main.cpp calls constructors for the input loading, lcp downloading, ignitions processing, WindNinja processessng and running, weather processing and running, and Farsite processing and running classes. Most of these classes do not do much during construction, but the inputs class does a lot during construction, including setting up a general list of all available and possible inputs.
2) command line inputs are processed to determine if they are valid, and if they are not, the inputs information is printed
3) if command line inputs are good, the inputs file to the script are loaded. This process is quite complicated, but basically everything is read into a vector of vectors (lines and words per line) where separators are used to determine what the words mean (variable name, number of values or single value, list of values) in order to give each line a type (variable name, value listing, empty line, comment line). The order of the word types is checked to make sure input syntax is valid. If input syntax is valid, the list of variable names are checked to see if the user specified a bad combination of inputs. If the minimum required inputs are in the file, with the right combinations of inputs, the input class then loads in all the values for each input, warning if they are not valid to the format or types used in the input storage container classes. These input values are then used by all the rest of the code by calling the inputVariablesHandler class which manages data transfer with the input variable storage classes.
3-stopToExplain) if the inputs are loaded in correctly, the rest of the code runs, doing the required tasks for each of the other classes, quitting at any time an error occurs. The usual process is to make a call to a semi constructor for each class, passing in all the inputs temporarily so that the class can grab and store into itself all the inputs it needs as their basic type without always needing the full set of inputs. Then functions for a given class are run using these stored inputs.
4) the order of whether to process the ignitions into a form suitable for Farsite or whether to automatically download an lcp file is a bit convoluted and might change. Basically both classes need each other, and the order depends on whether files are just given or if downloading is required. But basically the lcpDownloader class just downloads an lcp file using the largest input ignition size and a multiplication factor. The createIgnitions class processes the input ignition files to make new copies that are in the form required by Farsite (matching projection of lcp to ignition file, turning point ignitions into small polygons, grabbing the last fire perimeter of an old farsite run to use as a starting ignition).
5) the WindNinjaAPI class is not the same as the actual WindNinja API (yet), but basically creates the input config files for running WindNinja, runs WindNinja, then uses WindNinja logs to get the times for each WRF file (this might not be the best spot to grab these times).
6) the wrfGetWeather class goes through the input WRF files to obtain temperature, precipitation, cloud cover, and other variables needed for the RAWS input in Farsite. Since these values are for the entire field, but Farsite RAWS files only want a single value, different choices for interpolation or point selection are used depending on user input.
7) the farsiteAPI class takes information from each of the other classes to setup a list of all files and inputs required to run Farsite, then runs Farsite. It will also be where post processing of results can be added later.



#################  General Overview for Building and Running the Script  #################

The basic idea of this script is that running /include/buildEverything.sh downloads, unpacks, and builds all required libraries and required separate applications, writes a required cmake file to update the paths to all these dependencies, and builds the WRF-WindNinja_FarsiteScript, putting the executable in the bin/ directory. Then you run the script from the command line without a proper input file to get help on what is required in the input file, then run the script from the command line with a path to the required input file to run the script.

If there is anything wrong with the inputs, the input parser should catch the problem and warn if input data is off or more is required. The script also has error checking to stop at any point that it runs into trouble, so if you have problems without getting understandable errors, somehow you've caused an edge case where the programmers need to add some more error checking.

If there is anything wrong with running buildEverything.sh, it should stop and warn where in the process an error has occured so you can go into the file and edit the download source links or any other required unpacked filenames that might have changed. Running buildEverything.sh multiple times should warn if different files are already found so it avoids redoing steps in the process unless you delete files. Instead of manually deleting files, there are individual "shouldMakeClean" boolean values you can set for a given package where the script will handle deleting old build files for you for a clean build.

The example input files should now run after buildEverything.sh runs properly, as this script also takes the keyword "$scriptRoot" and replaces it with the correct path to home for the user. Note that only one of the example config files is meant to run to completion because only one of these files uses enough wrf files and the correct start and end farsite simulation times to get farsite to process anything.

Of the current examples, the expected behavior for firstRunCougarCreek.txt is as follows: firstRunCougarCreek.txt will run all the way to completion, and you can use the resulting a-originalInputs/cougarCreek.lcp with its corresponding projection file and a-originalInputs/colorInput.CLR files in farsite4 from firelab.org to view the lcp of the example. You can then take info from the finalOutputs folder to view the resulting fire stuff in said farsite4. Eventually will move on to use flammap6 instead of farsite4 for viewing.

For other current examples, the code will stop at farsite, as there are not enough wind files for said cases, but they will show output resulting empty folders as it attempts to run multiple separate fires for different ignition files on a single set of wind data. Just there are not enough wind files (min of 1 day's worth before the fire) for farsite to actually run with the inputs provided by the outputs of everything else (not enough wrf files as input to the entire script).

A quick clarification, the buildEverything_Ubuntu.sh uses "sudo ldconfig", "sudo make install", and "sudo apt-get install" to get all the packages, buildEverything_UbuntuAlternative.sh does enough of the same thing without these commands by building custom directories for everything, including WindNinja, where the script also avoids running WindNinja's build_deps.sh script. And buildEverything_Aeolus.sh is similar to buildEverything_UbuntuAlternative.sh in that no sudo is allowed on Aeolus. If you have any trouble with packages built to custom directories, it may be helpful to look at old versions of these files for ideas, as curl with gnutls is the only package really not built completely from scratch that may cause trouble in the future.


If you have any trouble using this script or have any suggestions, email the original developer, Loren Atwood, at pianotocador@gmail.com



#################  General Overview of WRF-WindNinja-FarsiteScript Examples  #################

For now the only examples revolve around a single cougarCreek landscape file. The three different input files for WRF-WindNinja-FarsiteScript are firstRunCougarCreek.txt (runs to completion), runcougarCreek.txt (not enough inputs to run all the way through Farsite), template-runcougarCreek.txt (similar to runcougarCreek.txt, but now more ignitions at once, functionality not fully built yet). Each of these input files are pulling inputs to the WRF-WindNinja-FarsiteScript from the a-originalInputs folder, which contains a bunch of ignition files, wrf files, and the input landscape .lcp file. When running WRF-WindNinja-FarsiteScript with these input files, the createInputs and finalOutput folders are created. The ones that are currently carried around with the repo are those generated by running the firstRunCougarCreek.txt input file.

The createInputs folder contains files generated by the WRF-WindNinja-FarsiteScript by running createIgnitions, WindNinja, and wrfGetWeather for running in Farsite. The WindNinja folder contains outputs for each WindNinja run while the Farsite folder contains all files to be used if running Farsite by itself. In the Farsite folder, the .raws files are from stuff from wrfGetWeather, the .atm and .asc files (with their .prj files) are those grabbed from the WindNinja folder, the ignition .shp files (with all associated .shx, dbf, and .prj files) are created by createIgnitions, the .input file is created to point to all these files as inputs, the run_cougarCreek_polygonIgnit.txt file is the file fed into farsite at the command line to run Farsite (points to more inputs).

The finalOutput folder contains files generated by WRF-WindNinja-FarsiteScript running Farsite with the createInputs/Farsite stuff as input. To look at the results, probably need the .lcp and .clr files from the a-originalInputs folder for viewing with these output files.



#################  Step by Step Guide for Building and Running the Script  #################


The following worked on fresh installations of Ubuntu 16.04 and 18.04 on a virtual machine or Windows Subsystem of Ubuntu:

sudo apt update
sudo apt upgrade
sudo apt install git
git clone https://github.com/latwood/WRF-WindNinja-FarsiteScript.git
cd WRF-WindNinja-FarsiteScript/include
./buildEverything_Ubuntu.sh 2>&1 | tee buildEverything.log

Used to be that you needed to run "sudo make install" and "sudo ldconfig" in order to have at least one fully installed version of WindNinja in order for the current pipeline call of WindNinja to work properly. This is not true anymore, though the buildEverything_Ubuntu.sh script still runs "sudo ldconfig". But it is still true that the user's .bashrc file needs modified with a version of "export WINDNINJA_DATA=~/src/wind/windninja/data". If you already have multiple versions of WindNinja, you probably can skip this step. You can also use buildEverything_UbuntuAlternative.sh with no problems.

now add the a modified version of this to your .bashrc file (found in $HOME):
export WINDNINJA_DATA=/PATHTOSCRIPTREPO/WRF-WindNinja-FarsiteScript/include/extraApps/windninja/data

run the following to update .bashrc usage
source $HOME/.bashrc


The script is now fully compiled. Here is an example of a run:
cd /WRF-WindNinja-FarsiteScript/bin/
./WRF-WindNinja-FarsiteScript ../examples/cougarCreek/firstRunCougarCreek.txt 2>&1 | tee scriptRun.log



Note that buildEverything takes completely different times depending on the computer, I've seen it take 2 hours on a virtual machine of Ubuntu on my relatively fast computer, to 4 hours with the Windows Subsystem of Ubuntu (which be warned, can pause periodically). Password injection has been dropped cause that idea failed, so expect the script to pause and ask you for your password again, especially during the WindNinja installation part. On slow computers (Windows Subsystem of Ubuntu), I've seen the build_deps.sh script run for WindNinja ask for passwords multiple times.
Note that the example run in this case is the one that goes to completion, which takes about 14.5 minutes on my relatively fast computer. It might be helpful to try out one of the other examples that take less time just to see if the installation succeeded or not. If things don't at least get to the farsite step, there's a problem.

Step by step method to view results on a Windows machine. If you don't want to install farsite, your on your own, just need some kind of GIS software:
go to https://www.firelab.org/, on this webpage look for "apps and products/fire behavior/farsite". On this farsite page, look for "farsite software". This leads you to a farsite for windows installer.
After installing farsite, run farsite, and in the menu search for "view/view landscape file (.LCP)/2D window". Use the "cougarCreek.lcp" file.
After the file loads, right click the section of the box labeled "Visible Theme" in the section with the numbers and colors. This should pop up a menu "Choose Color Ramp". Select "Load Color File (.CLR)" and use the "colorInput.CLR" file. Note you need to make your own if doing a different .lcp file than this example, I randomly changed colors till it looked good, then saved this color scheme.
In the menu search for "view/View Vector File". Change the extensions it is looking for to ".shp", then you can view the "cougarCreek_Perimeters.shp" fire perimeters and "cougarCreek_Spots.shp" probabilistic spot location files. Need to select the boxes labeled "2D" to get the files to actually show the pictures, left click the lines or dots to choose colors, right click to choose the sizes.
Note that you can see other files as well, but might need to hunt down their specific types using either "vector" or "raster" input from the "view" menu.

These above instructions are exactly the same with buildEverything_UbuntuAlternative.sh, just replace buildEverything_Ubuntu.sh with buildEverything_UbuntuAlternative.sh


To build on Aeolus, you will need to make some slight modifications to the buildEverything_Aeolus.sh. You will probably also need to download said file to another location where you can push it up to Aeolus when you are ready to run this compilation script:

scp buildEverything_Aeolus.sh <username>@aeolus.wsu.edu:/home/<username>/buildEverything_Aeolus.sh
ssh <username>@aeolus.wsu.edu

Important things to modify are (outputDir) will be where the WRF-WindNinja-FarsiteScript repo will be downloaded to and is specific to your system, (overallScriptOutputDir) is where the script expects you to copy the resulting examples directory before running the runComboScriptExample.sh required to run the WRF-WindNinja-FarsiteScript after compilation. It is probably also wise to change the email and any other user specific stuff to run the script that is in the first section before any of the normal variables.
The following worked on Aeolus, which is a CentOS system where all uses of "sudo" are not allowed:

qsub -I
qsub buildEverything_Aeolus.sh
qstat -u <username>    (useful to know how the compilation run is going)

if it builds successfully, you need to do the following once before running the script
now add the a modified version of this to your .bashrc file (found in $HOME):
export WINDNINJA_DATA=/PATHTOSCRIPTREPO/WRF-WindNinja-FarsiteScript/include/extraApps/windninja/data

run the following to update .bashrc usage
source $HOME/.bashrc

After modifying your runComboScriptExample.sh, you need to copy the WRF-WindNinja-FarsiteScript/examples dir to whereever you set (overallScriptOutputDir) to. If you are not happy with said compile time location, you should use a version of the sed command in the examples dir to update where the expected inputs and outputs should be found or where they should be run from.
qsub -I
mkdir /(overallScriptOutputDir location)/WRF-WindNinja-FarsiteScript
cp -r /PATHTOSCRIPTREPO/WRF-WindNinja-FarsiteScript/examples /(overallScriptOutputDir location)/WRF-WindNinja-FarsiteScript/
qsub runComboScriptExample.sh
qstat -u <username>   (useful to know how the compilation run is going)


Currently this is working on Aeolus, but apparently the cpus on Aeolus are crazy slow compared to my regular computer. The same runs that took 14 or so minutes on my regular computer take over 40 minutes on Aeolus with similar resources. It may be necessary to change the input files to WRF-WindNinja-FarsiteScript manually to increase the number of threads to use in WindNinja runs, as I've tracked down the slowdown to be that WindNinja runs take 8 seconds on my regular computer, but 30 seconds on Aeolus with similar resources. At around 80 WRF files to process, 80*8 seconds ~ 10 minutes, while 80*30 seconds ~ 40 minutes. There may also be rules saying you need to write to fastscratch or scratch only, not your local login node location, though I've had trouble getting scratch to let me use it.


Note for all builds, but especially Aeolus builds. While it is still necessary to call "git update-index --assume-unchanged <file of interest>" manually from the command line to retrack example, config, and other files untracked during compile time, updating variables using the sed command has been moved to a useful utility script called keywordReplacer.sh. This file lets you only use sed to replace variables in specific locations, but does it to all files in the directory, so it could be helpful for quick changes of files with sed. Just open the keywordReplacer.sh file to get an idea of how to use it, or look for uses of it in buildEverything.sh scripts.


#################  Close to Step by Step description of buildEverything.sh    and     General Dependency List      #################

This is too complicated to go into in detail, though it existed before, see old git commits to find this info before changes were made to build on Aeolus. The buildEverything.sh scripts should be pretty clear on what dependencies and order of operations are just by reading the scripts.




#################  Close to Step by Step description of wrfTrimmer.sh  #################

Description of utility_scripts/wrfTrimmer.sh
--Makes sure the input directory does not match the output directory
--Uses "/*" on input folder to grab all files in folder
--Sets up a counter for nFilesLookedAt and nWrfFiles processed
--Uses "ncdump -h" on each and every file to see which are valid netcdf files. Sends output away in a suppressed manner using ">" to "/dev/null 2>&1" since valid netcdf files are those for which "ncdump" works without error
--If a file is found to be a valid netcdf files, "ncks -v" with the required data information for the overall script is used to trim the files
--If a file is found to be a valid netcdf file, but "ncks" fails when trimming it, the process is stopped with an error
Note that if the newly trimmed file location would be overwriting a file with the same name, "ncks" is nice and warns and gives the option to overwrite or skip before doing continuing.



###############  Future todos, order doesn't necessarily matter  ###############

Severe todos first
2) make sure all input variable names and descriptions make sense and that all default variables and whether the booleans warning if they are currently in use by functions yet have been set properly.
3) make sure all units are being processed correctly, track down why farsite keeps warning of some kind of unreal moisture problem that it seems to think is caused by a bad combination of weather inputs.
4) the developer scripts have been organized, now use them to test preprocessing of ignition files for farsite. The idea is to test individual ignition file preprocessing outside of WRF-WindNinja-FarsiteScript, then put the resulting methods into WRF-WindNinja-FarsiteScript.

Future hoped for work
1) update the input lists to include all WindNinja mass only inputs so a choice to use domain avg runs or weather downloads or any normal mass only stuff with farsite instead of just wrf files.
2) update the input lists to include all farsite variables, this would also finally be a chance to set explanations that make sense for what the heck farsite even wants as inputs.
3) try to eliminate the info vs variables storage classes being separate by combining them using pointer functions to the input variables classes. This may or may not be easy, but should hopefully stop the problem in the input class where when a developer wants to add a new input, where to modify is all over the place.
4) try to automate lcp file downloads, ignition downloads, other downloads. For now, AIRPACT will handle the downloads on their end, but might be nice long long long term.
5) change WindNinja API to actually use WindNinja directly as an API. Maybe also modify farsite a bunch more to turn it into a library as well to avoid all system calls. Currently pipeline calls are done not system calls, but doing calls via library is way more C++ standardlike.
6) update farsite to fit more with what is being done in Windows Farsite and Assembla Farsite. This would be a ton of work, and should be avoided at all costs till very last.
7) Figure out a smarter way to know how to deal with lcp vs fire perimeter input stuff.
8) Could do this one sooner than later, stop the delayed command line output printing by changing all print functions from printf to cout. This would entail adding some library utility functions called by whatever needs them for doing value to string conversions so cout won't choke.


###############  For future developer notes, links may need updated depending on pushes to repo  #######################

### changing an already existing input variable to the WRF-WindNinja-FarsiteScript, or adding a new input variable but with an already existing input variable type  ###

You will need to modify an existing instance of "addVariable" or create a new instance of "addVariable()" in "inputVariable_infoStorage::setupAvailableVariables()", found in inputVariable_infoStorage.cpp: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_infoStorage.cpp#L124. You will be warned if you try to use an invalid applicationUseName or variable type, or even if the "addVariable()" function calls aren't in a proper order.

If the input variable has an expected default value that is different from the standard default value given by a given variable type class, you will need to modify some part of "inputVariables_valueStorage::setSpecializedDefaults()" found in inputVariable_valueStorage.cpp: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.cpp#L1057.

All new variables or existing variables need to have conflicting options or non-conflicting options checked out. So you will need to modify "inputVariablesHandler::verifyFoundInputCombinations()" found in inputVariablesHandler.cpp: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariablesHandler.cpp#L466. Depending on the changes, you may have to mess with the various "inputVariablesHandler::checkUsage_<usageType>" functions. Honestly these might already need some work/double checking.

This should be enough unless you are dealing with something with type "string". This is because when a value of type "string" is read into the input classes, a check to see whether it is an allowable word or not for the string must be done. So you will need to modify by adding a new entry for your specific string the "stringValue::isValidString()" function found in stringValue.cpp: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/singleValueDataTypes/stringValue.cpp#L101. 


### adding a new input variable that requires adding a new input variable type, and is for a single value of input  ###

Hopefully all the required information is here, this stuff can be all over the place!!!

No need to mess with inputVariable_info.cpp.
Besides all the above stuff for changing a variable with an existing type, you should probably start at "inputVariable_infoStorage.cpp". You may need to add to the existing "applicationUseName" variables or change their order: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_infoStorage.cpp#L84. You will definitely need to add a new variable count type: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_infoStorage.cpp#L98. Just remember that if you create a type here, you need to create all the uses of that type in other parts of the code!!!.

The next step would be to create the new type classes. The singleValueDataTypes/ folder has all the existing single value data type: https://github.com/latwood/WRF-WindNinja-FarsiteScript/tree/master/src/inputClasses/singleValueDataTypes. Copy and paste the header and .cpp files of whichever one you want to pattern after and rename whatever you need to create your new type. There will always be a reset() function, a setValue() function for regular input as well as a setValue() function for parsed string input from the data parser, some kind of getValue() function, whatever type conversion functions are needed to go from string to the value, whatever type checker to determine if a string of the value can be converted or not, data members for the actual values of the given class type, and default values to set the actual values of the given class type at each call to the class type reset() function.

Now the new data type class needs to be added to the CmakeLists file. Add the appropriate path patterned after the other single inputs: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/CMakeLists.txt#L61.

Now need to start messing with inputVariable_valueStorage. First add the appropriate header file: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.h#L7, and the appropriate vector of said values to the data members: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.h#L126. Add copies of the data type class public set and get functions: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.h#L45, https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.h#L91.

Add a required inputVariable_valueStorage::resetVariables() reset() function for the new variable type: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.cpp#L33. Create the new set and get value functions for the new input variable type: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.cpp#L118, https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.cpp#L143, https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.cpp#L760. Add an instance of shoving the new values for the new class variable into the new vector of values of this type in the inputVariable_valueStorage::sortInputVariableInfo() function: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariables_valueStorage.cpp#L996. 

Now time to move on to the inputParser. You will need to add the specific type calls to the new class variable set() functions that set string values to the actual values. This is found in inputParser::loadCountValues(): https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputParser.cpp#L211.

Now to the very last main input class: inputVariablesHandler. Unfortunately, there is a lot of stuff repeated here that is done by inputVariables_valueStorage. Work to try to use pointers to the given variable type classes has been started in a separate branch that will mean rewriting this whole developer help section, but at least would get rid of this repeatedness and decrease the number of times stuff is stored. But it requires very strong knowledge of pointers, and probably the rule of 3 with the copy constructor and assignment operator to work correctly.

Need to add the copy of the get() functions: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariablesHandler.h#L35. The inputVariablesHandler::printFoundInput() function is used for debugging purposes, but still should be updated. Add the required printing of the values to this function: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariablesHandler.cpp#L172. The code implementation of the getValue() functions are easier this time, but still need to add them: https://github.com/latwood/WRF-WindNinja-FarsiteScript/blob/master/src/inputClasses/inputVariablesHandler.cpp#L338.

Okay, that SHOULD be everything. I guess be aware that there are embedded types, so you may not need to make a new type of double, but add implementation of the type to the doubleValue class. You will notice that the lat_coord, long_coord, and signless_percent are all examples of this.


### adding a new input variable that requires adding a new input variable type, and is for multiple values of input  ###

Pretty similar to adding a single line of input type variable, but now you don't need to necessarily add a type to inputVariables_infoStorage.cpp since these are of type "count". Now the folder of locations is https://github.com/latwood/WRF-WindNinja-FarsiteScript/tree/master/src/inputClasses/multiValueDataTypes. Watch out in the CmakeLists that you keep the single values separate from the multiple value input classes. Be aware that these usually have multiple types/data members inside and so actually use some of the singleValue input variable classes as datatypes. This also means pulling out and setting values tends to be one at a time to some extent instead of all at once, so look at the other examples of multipleValue type storage. Honestly, some of these ideas Could be improved.

Probably the biggest difference is that now you don't have to edit inputParser::loadCountValues(), because the type is "count" which is type "size_tValue". But now you need to mess with inputParser::loadLoaderFunctionData().