OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
GenerateOpalSimulation.h
Go to the documentation of this file.
1 //
2 // Class GenerateOpalSimulation
3 // Generates an OPAL input file from data and template file.
4 //
5 // When running the optimizer with the OPAL forward solvers this utility
6 // class helps generating OPAL input files corresponding to the design
7 // variable values of the requested evaluation.
8 // Using the data file we start by generating the dictionary of known
9 // templates.
10 // When the input file is requested, all template variables in the template
11 // input file are replaced with values found in the dictionary.
12 //
13 // TODO:
14 // - pass stream directly to opal (detour over file not necessary)
15 //
16 // Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
17 // All rights reserved
18 //
19 // Implemented as part of the PhD thesis
20 // "Toward massively parallel multi-objective optimization with application to
21 // particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
22 //
23 // This file is part of OPAL.
24 //
25 // OPAL is free software: you can redistribute it and/or modify
26 // it under the terms of the GNU General Public License as published by
27 // the Free Software Foundation, either version 3 of the License, or
28 // (at your option) any later version.
29 //
30 // You should have received a copy of the GNU General Public License
31 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
32 //
33 #ifndef __GENERATE_SIMULATION_H__
34 #define __GENERATE_SIMULATION_H__
35 
36 #include <iostream>
37 #include <fstream>
38 #include <sstream>
39 #include <string>
40 #include <map>
41 #include <cstdlib>
42 
43 #include <vector>
44 #include <boost/algorithm/string.hpp>
45 #include "boost/filesystem.hpp"
46 
47 #include "Util/OptPilotException.h"
48 
50 
51 public:
52 
61  GenerateOpalSimulation(std::string tmplFile, std::string varDictionary,
62  std::map<std::string,std::string> userValues) {
63  varDictionary_ = varDictionary;
64  tmplFile_ = tmplFile;
65 
66  // some variables need to be scaled
67  scaleVars_.insert(std::pair<std::string, double>("GUNSOLB", 1.));
68 
69  // add user values and then fill using the data file without
70  // overwriting user values..
71  dictionary_.insert(userValues.begin(),userValues.end());
73  }
74 
76  dictionary_.clear();
77  scaleVars_.clear();
78  }
79 
86  void writeInputFile(std::string outputFile) {
87 
88  std::ifstream infile(tmplFile_.c_str());
89  std::ostringstream outdata;
90  outdata.precision(15);
91 
92  while(infile.good()) {
93  std::string line;
94  std::getline(infile, line, '\n');
95 
96  //XXX doing the inverse would be better
98  for(;itr != dictionary_.end(); itr++) {
99  size_t pos = line.find("_" + itr->first + "_");
100  while(pos != std::string::npos) {
101  line.replace(pos, itr->first.length() + 2, itr->second);
102  pos = line.find("_" + itr->first + "_");
103  }
104  }
105 
106  outdata << line << std::endl;
107  }
108  infile.close();
109 
110  // ensure the contents are written to disk
111  std::ofstream outfile(outputFile.c_str());
112  outfile.precision(15);
113  outfile << outdata.str();
114  outfile.flush();
115  outfile.rdbuf()->pubsync();
116 
117  outfile.close();
118  }
119 
120 
121 private:
122 
124  std::string tmplFile_;
126  std::string varDictionary_;
128  std::map<std::string, std::string> dictionary_;
130  std::map<std::string, double> scaleVars_;
131 
145  void fillDictionary() {
146 
147  namespace fs = boost::filesystem;
148 
149  fs::path pwd = fs::current_path();
150  if (!fs::exists(varDictionary_) || fs::is_empty(varDictionary_))
151  return;
152 
153  std::ifstream infile;
154  infile.open(varDictionary_.c_str(), std::ifstream::in);
155 
156  char tmp[1024];
157  unsigned int line_nr = 0;
158  while(infile.good()) {
159  std::fill_n(tmp, 1024, '\0');
160  infile.getline(tmp, 1024);
161  line_nr++;
162  if(tmp[0] != '#') {
163  std::string stmp(tmp);
164  boost::trim(stmp);
165  if(stmp.size() == 0)
166  continue;
167 
168  std::vector<std::string> all_strings;
169  boost::split(all_strings, stmp,
170  boost::is_any_of("\r\n\v\f\t "),
171  boost::token_compress_on);
172 
173  if(all_strings.size() < 2) {
174  std::cout << "PROBLEM with the following line "
175  << "(at least name and value required)!"
176  << std::endl;
177  std::cout << stmp << std::endl;
178  std::ostringstream ex;
179  ex << "Invalid data file on line " << line_nr;
180  throw OptPilotException(
181  "GenerateOpalSimulation::fillDictionary()",
182  ex.str());
183  }
184 
185  std::string varname = all_strings[0];
186  std::string value = all_strings[1];
187  scale(varname, &value);
188  dictionary_.insert(std::pair<std::string, std::string>(
189  varname, value));
190  }
191  }
192 
193  infile.close();
194  }
195 
196 
198  void scale(std::string name, std::string *value) {
199  if(scaleVars_.count(name) > 0) {
200  std::istringstream instr(*value);
201  double val;
202  instr >> val;
203  val *= scaleVars_[name];
204 
205  // we keep values as strings, since we have to write them to
206  // output streams anyways..
207  std::ostringstream of;
208  of << val;
209  *value = of.str();
210  }
211  }
212 
213 };
214 
215 #endif
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
const std::string name
std::string::iterator iterator
Definition: MSLang.h:16
FRONT * fs
Definition: hypervolume.cpp:59
void scale(std::string name, std::string *value)
Helper method to scale variable if necessary.
std::string tmplFile_
template filename
std::map< std::string, double > scaleVars_
holds all variables that need scaling
void writeInputFile(std::string outputFile)
GenerateOpalSimulation(std::string tmplFile, std::string varDictionary, std::map< std::string, std::string > userValues)
std::map< std::string, std::string > dictionary_
holds parsed template data
std::string varDictionary_
data filename