-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathODECommandLine.cpp
365 lines (313 loc) · 12.7 KB
/
ODECommandLine.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/******************************************************************************
*/
#include "ODECommandLine.h"
namespace STOCHKIT
{
ODECommandLine::ODECommandLine(int ac, char* av[]):
visible("command line options")
{
std::string temp_dir;
visible.add_options()
("model,m", boost::program_options::value<std::string>(&modelFileName),"**REQUIRED Model file name")
("time,t",boost::program_options::value<double>(&simulationTime),"**REQUIRED Simulation time (i.e. run each realization from t=0 to t=time)")
("intervals,i",boost::program_options::value<std::size_t>(&intervals)->default_value(10),"Number of intervals.\n0=keep data only at simulation end time.\n1=keep data at start and end time.\n2=keep data at start, middle, and end times.\netc.\nNote data is stored at (intervals+1) time points.")
("reltol,r",boost::program_options::value<double>(&RTOL)->default_value(1e-6),"Relative tolerance of ODE solver.")
("abstol,a",boost::program_options::value<double>(&ATOL)->default_value(1e-9),"Absolute tolderance of ODE solver.")
("mxsteps",boost::program_options::value<unsigned int>(&MXSTEPS)->default_value(10000),"Maximum number of steps taken by ODE solver.")
("species",boost::program_options::value<std::vector<std::string> >()->multitoken(),"List of subset of species (names or indices) to include in output. If not specified, all species are included in output.")
("rate-constants",boost::program_options::value<std::vector<std::string> >()->multitoken(),"List of subset of rate constants (in the format of names of reactions) to include in sensitivity analysis in a pure mass action reaction system. If not specified, all rate constants are included in sensitivity analysis. CANNOT be used simultaneously with --parameters")
("parameters",boost::program_options::value<std::vector<std::string> >()->multitoken(),"List of subset of parameters (in the format of names of parameters) to include in sensitivity analysis. If not specified, all rate constants or parameters are included in sensitivity analysis. CANNOT be used simultaneously with --rate-constants")
("label","Label columns with species names")
("out-dir",boost::program_options::value<std::string>(&temp_dir),"Specify the output directory (default is <model name>_output.")
("sensi","Include forward sensitivity analysis for pure mass-action reaction system.")
("force,f","Overwrite existing output directory and output files without confirmation.")
("help,h","Use -h or --help to list all arguments")
;
hidden.add_options()
("ode-template", boost::program_options::value<std::string>(&ODETemplateFileName),"ODE Template file name")
;
combined.add(visible).add(hidden);
parse(ac, av);
//save command-line arguments
//skip the first (av[0] is the executable name)
*av++;
ac--;
//pull off the arguments
while (ac--) {
cmdArgs+=" "+(std::string)*av++;
}
#ifdef WIN32
//find the model file path and add quote for window version
//for "-m"
std::string serchingString="-m "+modelFileName;
std::string replaceString="-m "+(std::string)"\""+modelFileName+(std::string)"\"";
int index=cmdArgs.find(serchingString, 0);
if(index!=std::string::npos)
cmdArgs.replace(index, serchingString.size(), replaceString);
//for "--model"
serchingString="--model "+modelFileName;
replaceString="-m "+(std::string)"\""+modelFileName+(std::string)"\"";
index=cmdArgs.find(serchingString, 0);
if(index!=std::string::npos)
cmdArgs.replace(index, serchingString.size(), replaceString);
//for "--out-dir"
serchingString="--out-dir "+temp_dir;
replaceString="--out-dir "+(std::string)"\""+temp_dir+(std::string)"\"";
index=cmdArgs.find(serchingString, 0);
if(index!=std::string::npos)
cmdArgs.replace(index, serchingString.size(), replaceString);
#endif
}
std::string ODECommandLine::getGeneratedCodeDir() const {
return generatedCodeDir;
}
std::string ODECommandLine::getModelFileName() const {
return modelFileName;
}
std::string ODECommandLine::getODETemplateFileName() const {
return ODETemplateFileName;
}
double ODECommandLine::getSimulationTime() const {
return simulationTime;
}
std::size_t ODECommandLine::getIntervals() const {
return intervals;
}
/*
std::vector<std::string> ODECommandLine::getSpecies() const {
return species;
}
*/
std::vector<std::size_t> ODECommandLine::getSpeciesSubset() const {
return speciesSubset;
}
std::vector<std::string> ODECommandLine::getRateConstantsSubset() const {
return rateconstants;
}
std::vector<std::string> ODECommandLine::getParametersSubset() const {
return parameters;
}
bool ODECommandLine::getParameterFromParametersList() const {
return parameter_from_parameters_list;
}
bool ODECommandLine::getLabel() const {
return label;
}
std::vector<std::string> ODECommandLine::getSpeciesNames() const {
return speciesNames;
}
std::string ODECommandLine::getOutputDir() const {
return outputDir;
}
bool ODECommandLine::getUseExistingOutputDirs() const {
return useExistingOutputDirs;
}
bool ODECommandLine::getForce() const {
return force;
}
bool ODECommandLine::getSensiFlag() const {
return sensi;
}
std::string ODECommandLine::getCmdArgs() const {
return cmdArgs;
}
double ODECommandLine::getRTOL() const {
return RTOL;
}
double ODECommandLine::getATOL() const {
return ATOL;
}
unsigned int ODECommandLine::getMXSTEPS() const {
return MXSTEPS;
}
void ODECommandLine::parse(int ac, char* av[]) {
try {
boost::program_options::store(boost::program_options::parse_command_line(ac,av,combined), vm);
}
catch (...) {
std::cout << "StochKit ERROR (ODECommandLine::parse): unable to parse command-line arguments. Run with --help for a list of required and optional parameters.\n";
exit(1);
}
boost::program_options::notify(vm);
if (vm.count("help")) {
std::cout << visible;
exit(0);
}
if (!(vm.count("model") && vm.count("time") )) {
std::cout << "StochKit ERROR (ODECommandLine::parse): missing required parameter(s). Run with --help for a list of required and optional parameters.\n";
exit(1);
}
if (vm.count("ATOL")) {
if(ATOL <= 0.0) {
std::cout << "StochKit ERROR (ODECommandLine::parse): ATOL must be a number greater than zero" << std::endl;
exit(1);
}
}
if (vm.count("RTOL")) {
if(RTOL <= 0.0) {
std::cout << "StochKit ERROR (ODECommandLine::parse): RTOL must be a number greater than zero" << std::endl;
exit(1);
}
}
if (vm.count("MXSTEPS")) {
if(MXSTEPS <= 0) {
std::cout << "StochKit ERROR (ODECommandLine::parse): MXSTEPS must be a number greater than zero" << std::endl;
exit(1);
}
}
if (vm.count("species")) {
species=vm["species"].as<std::vector<std::string> >();
}
parameter_from_parameters_list = false;
if (vm.count("parameters")) {
parameters=vm["parameters"].as<std::vector<std::string> >();
parameter_from_parameters_list = true;
}
if (vm.count("rate-constants")) {
if(parameter_from_parameters_list == true){
std::cout << "StochKit ERROR (ODECommandLine::parse): --parameters and --rate-constants can not be simultaneously specified. Run with --help for a list of required and optional parameters.\n";
exit(1);
} else {
rateconstants=vm["rate-constants"].as<std::vector<std::string> >();
}
}
if (vm.count("label")) {
label=true;
}
else {
label=false;
}
if (vm.count("force")) {
force=true;
}
else {
force=false;
}
if (vm.count("sensi")) {
sensi=true;
}
else {
sensi=false;
}
if (vm.count("out-dir")) {
//create full path to output directory
outputDir=boost::filesystem::system_complete(boost::filesystem::path(vm["out-dir"].as<std::string>())).string();
}
else {
//create full path to output directory, default location, <full_path_to/model_filename (without extension)>_output
std::string tmp_full_model_path=boost::filesystem::system_complete(modelFileName).string();
outputDir=tmp_full_model_path.substr(0,tmp_full_model_path.find_last_of("."))+"_output_ode";
}
std::string full_model_path=boost::filesystem::system_complete(modelFileName).string();
generatedCodeDir=full_model_path.substr(0,full_model_path.find_last_of("."))+"_generated_code_ode";
if (vm.count("use-existing-output-dirs")) {
useExistingOutputDirs=true;
}
else {
useExistingOutputDirs=false;
}
//if user only wants a subset of species or wants species labels
//we have to read in the model file to get species names (and species subset, if needed), so do that now...
char modelFile[2048];
strncpy(modelFile,modelFileName.c_str(),2048);
Input_tag<ModelTag> input_model_tag(modelFile);
ModelTag model_tag = input_model_tag.writeModelTag();
ModelTag::ModelType modelType = model_tag.Type;
std::vector<std::string> modelSpeciesList=model_tag.SpeciesList;
if(vm.count("rate-constants") && modelType == ModelTag::mixed){
std::cout << "StochKit ERROR (ODECommandLine::parse): --rate-constants can not be used for mixed models which contain customized propensity functions.\n";
exit(1);
}
// ODETemplateFileName=boost::filesystem::system_complete(boost::filesystem::path(vm["ode-template"].as<std::string>())).string();
if (!vm.count("ode-template")) {
//create full path to ode template file, default location, <full_path_to/model_filename (without extension)>_output
// std::string tmp_ode_template_file=boost::filesystem::system_complete(boost::filesystem::path(av[0])).parent_path().parent_path().string();
// ODETemplateFileName=tmp_ode_template_file+"/cvTemplate_dns.c";
char* temp_env_pointer;
temp_env_pointer = getenv("STOCHKIT_ODE");
if(temp_env_pointer == NULL){
std::cout << "StochKit ERROR (ODECommandLine::parse): Please set appropriate $STOCHKIT_ODE environment variable.\n";
exit(1);
}
std::string ode_dir(temp_env_pointer);
if(ode_dir.empty()){
std::cout << "StochKit ERROR (ODECommandLine::parse): Please set appropriate $STOCHKIT_ODE environment variable.\n";
exit(1);
} else {
if( modelType == ModelTag::mass_action ){
if(parameter_from_parameters_list == true) {
ODETemplateFileName = ode_dir+"/cvsTemplate_FSA_mixed_dns.c";
} else {
ODETemplateFileName = ode_dir+"/cvsTemplate_FSA_mass_action_dns.c";
}
} else {
ODETemplateFileName = ode_dir+"/cvsTemplate_FSA_mixed_dns.c";
}
}
}
if (species.size()!=0) {//we need to create a species subset vector and set it in output object
//loop over command line species list
//if it's an index (a number), store it in the list of species indexes
//if it's a species id (species name), look up it's index in the modelSpeciesList
for (std::size_t i=0; i!=species.size(); ++i) {
std::istringstream iss(species[i]);
std::size_t index;
iss >> index;
if (iss.fail()) {
for (std::size_t j=0; j!=modelSpeciesList.size(); ++j) {
if (species[i].compare(modelSpeciesList[j])==0) {
speciesSubset.push_back(j);
break;
}
}
}
else {
if (index<modelSpeciesList.size()) {
speciesSubset.push_back(index);
}
else {
std::cout << "StochKit ERROR (ODECommandLine::parse): species index \""<<index<<"\" larger than number of species (Note: indices start at 0, so largest index is "<<modelSpeciesList.size()-1<<")\n";
exit(1);
}
}
}
}
//create vector of species names
if (speciesSubset.size()==0) {//if keeping all species, use species label vector from model_tag
for(std::size_t index=0;index<modelSpeciesList.size();++index)
speciesSubset.push_back(index);
speciesNames=modelSpeciesList;
}
else {//we're using a species subset, so we need to create the appropriate species label subset
DenseVectorSubset<std::vector<std::string> > labelSubset(speciesSubset);
speciesNames=labelSubset.getSubset(modelSpeciesList);
}
if (species.size()!=0) {//we need to create a species subset vector and set it in output object
//loop over command line species list
//if it's an index (a number), store it in the list of species indexes
//if it's a species id (species name), look up it's index in the modelSpeciesList
for (std::size_t i=0; i!=species.size(); ++i) {
std::istringstream iss(species[i]);
std::size_t index;
iss >> index;
if (iss.fail()) {
for (std::size_t j=0; j!=modelSpeciesList.size(); ++j) {
if (species[i].compare(modelSpeciesList[j])==0) {
speciesSubset.push_back(j);
break;
}
}
}
else {
if (index<modelSpeciesList.size()) {
speciesSubset.push_back(index);
}
else {
std::cout << "StochKit ERROR (ODECommandLine::parse): species index \""<<index<<"\" larger than number of species (Note: indices start at 0, so largest index is "<<modelSpeciesList.size()-1<<")\n";
exit(1);
}
}
}
}
}//end parse
}