You can create your own new function to manipulate SS3 configuration files during an ss3sim simulation. All this function needs to do is read in the appropriate SS3 files, manipulate them in some way, and write them back out. You then need to insert your new function into the main ss3sim simulation routine so it gets called at the appropriate time. The following instructions briefly outline all the steps to this process. Feel free to contact any of the ss3sim developers for help. If you create a new manipulation function it would be great to get it incorporated into the official package.
The new manipulation function can be used by one or more cases. Cases can be mandatory (must be included in all scenarios, like
D) or optional like
S where if not specified then nothing occurs.
Write your change function in the
Aim for singular names (e.g.
Input and output file arguments should be written as
_file_out with a three character prefix before the first underscore indicating which file type (e.g.,
In general try to match argument names as best as possible. A good approach is to start with a similar function and modify as needed.
Unless otherwise necessary, arguments should take SS file names (as character values) and do the reading internally using r4ss functions (as opposed to taking lists that have already been read in by r4ss). Currently, there are a few places in ss3sim (e.g. the sampling functions) that take an already-read version as an argument value. This will be standardized eventually.
@author, etc. to document your function. Then run
devtools::check(cran = TRUE) on your new code. Test that the documentation is right with
Also make sure you have an example and can run
devtools::dev_example(your_change_function). Note that your example should not run SS3 itself. See other functions for how to create a working example from packaged files.
Now go to
You need to pick a capital letter to represent your case. This should be different than any existing case letter. E.g., at the time of writing this, the letters D, E, F, G, M, R, and S are being used.
Add your new letter to the
get_caseargs default argument values if you want it to be a mandatory case. Otherwise your new case letter must be passed explicitly in the
Add a new argument to the function
ss3sim_base that corresponds to your new case. For example,
f_params. Make sure to also document the new argument with roxygen2
Now that your case arguments are passed to this function, you can use them in the function call. So add a call to your function within the code of
ss3sim_base. Where in the code depends on when your function needs to be run in the flow of a simulation. The
change_f needs to occur before the OM runs, and the sampling of data occurs after the OM runs.
devtools::document() to update the argument list for
ss3sim_base and check it.
run_ss3sim needs to be updated to include your new case argument from step 3.
a is a list of list of arguments, one element of which is your new set of arguments. For instance
a$F will contain the vector of
Update the section that starts with
arg_list <- lapply(scenarios... to include your new argument. The list element name should correspond to the function name after
sample. For example,
a$lcomp corresponds to
change_lcomp. This is important for the case parsing to work properly. (Yes, there are some legacy arguments that don’t match and are hardcoded into the case parsing.)
If the case is optional and not passed, the element of the list will be NULL. That is,
a$X will be NULL if the case
X isn’t used. You can test for this in
ss3sim_base and skip your function, effectively turning it off if there is no case argument available. This will also prevent previous code from breaking.
Test your new function and make sure that all existing examples continue to work.
First test that
get_caseargs reads in and parses your case files properly. If your case isn’t mandatory you need to explicitly pass the cases to the
case_files argument. E.g. if your case is
case_files=list(M=M, F=F, D=c(index, lcomp, agecomp), R=R, E=E, X=X). This function will return a list of lists of the case arguments read from file.
You will have to do more work if your case is mandatory, since it will break any previous scenarios. You will have to: add new case files for the example models, the example code in the functions, and the vignette code.
Remember to run
devtools::document() after editing the examples.
In general, the user should be able to easily bypass your function and have it do nothing.
You can check all the examples with
Of course, do another
devtools::check(cran = TRUE). This will also test the vignette building.