VPTissue Reference Manual
TemplateFilePage.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 Universiteit Antwerpen
3  *
4  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
5  * the European Commission - subsequent versions of the EUPL (the "Licence");
6  * You may not use this work except in compliance with the Licence.
7  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the Licence is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the Licence for the specific language governing
13  * permissions and limitations under the Licence.
14  */
20 #include "TemplateFilePage.h"
21 
26 
27 #include <boost/property_tree/exceptions.hpp>
28 #include <boost/property_tree/xml_parser.hpp>
29 #include <QComboBox>
30 #include <QDoubleValidator>
31 #include <QFileDialog>
32 #include <QFormLayout>
33 #include <QLabel>
34 #include <QLineEdit>
35 #include <QListView>
36 #include <QListWidget>
37 #include <QMessageBox>
38 #include <QPushButton>
39 #include <QRadioButton>
40 #include <QRegExp>
41 #include <QRegExpValidator>
42 #include <QSettings>
43 #include <QString>
44 #include <QVBoxLayout>
45 
46 #include <algorithm>
47 #include <cctype>
48 #include <iostream>
49 #include <fstream>
50 #include <functional>
51 #include <locale>
52 #include <memory>
53 #include <sstream>
54 
55 using namespace boost::property_tree;
56 using namespace boost::property_tree::xml_parser;
57 
58 namespace SimPT_Parex {
59 
60 TemplateFilePage::TemplateFilePage(std::shared_ptr<Exploration> &exploration, boost::property_tree::ptree &preferences)
61  : m_exploration(exploration), m_preferences(preferences)
62 {
63  // Set title + text
64  setTitle("Select template sim data file");
65  setSubTitle("Select a sim data file template to use as basis for the exploration. Parameters should be entered as $param_name$. The params file should be a CSV file with the param_names as headers.");
66 
67  // Set main layout
68  QVBoxLayout* mainlayout = new QVBoxLayout;
69  QHBoxLayout* layout = new QHBoxLayout;
70  QLabel* label = new QLabel("Template");
71  m_file_path = new QLineEdit;
72  m_file_path->setReadOnly(true);
73  QPushButton* buttonBrowse = new QPushButton("Browse...");
74 
75  layout->addWidget(label);
76  layout->addWidget(m_file_path);
77  layout->addWidget(buttonBrowse);
78  mainlayout->addLayout(layout);
79 
80  layout = new QHBoxLayout;
81 
82  QLabel* labelparams = new QLabel("Params");
83  m_params_path = new QLineEdit;
84  m_params_path->setReadOnly(true);
85  QPushButton* buttonBrowseParams = new QPushButton("Browse...");
86 
87  layout->addWidget(labelparams);
88  layout->addWidget(m_params_path);
89  layout->addWidget(buttonBrowseParams);
90 
91  mainlayout->addLayout(layout);
92 
93  setLayout(mainlayout);
94 
95  connect(buttonBrowse, SIGNAL(clicked()), this, SLOT(BrowseLeafFile()));
96  connect(buttonBrowseParams, SIGNAL(clicked()), this, SLOT(BrowseParamsFile()));
97 }
98 
99 void TemplateFilePage::BrowseLeafFile()
100 {
101  QSettings settings;
102 
103  QString path;
104  if (settings.contains("last_template_file"))
105  path = settings.value("last_template_file").toString();
106  else
107  path = settings.value("workspace").toString();
108 
109  QString file = QFileDialog::getOpenFileName(this, "Browse", path);
110 
111  m_ptree.clear();
112 
113  if (!QFile(file).exists())
114  return;
115 
116  try {
117  read_xml(file.toStdString(), m_ptree, trim_whitespace);
118  } catch (ptree_bad_path& e) {
119  QMessageBox::critical(this, "Read Error", "Error in file", QMessageBox::Ok);
120  return;
121  } catch (ptree_bad_data& e) {
122  QMessageBox::critical(this, "Read Error", "Error in file.", QMessageBox::Ok);
123  return;
124  } catch (xml_parser_error& e) {
125  QMessageBox::critical(this, "Error", "Not a valid file.", QMessageBox::Ok);
126  return;
127  } catch (std::exception& e) {
128  QMessageBox::critical(this, "Error", "Could not read file.", QMessageBox::Ok);
129  return;
130  } catch (...) {
131  QMessageBox::critical(this, "Error", "Unknown Exception", QMessageBox::Ok);
132  return;
133  }
134 
135  m_file_path->setText(file);
136  settings.setValue("last_template_file", file);
137 
138  emit completeChanged();
139 }
140 
141 // trim from start
142 static inline std::string &ltrim(std::string &s) {
143  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
144  return s;
145 }
146 
147 // trim from end
148 static inline std::string &rtrim(std::string &s) {
149  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
150  return s;
151 }
152 
153 // trim from both ends
154 static inline std::string &trim(std::string &s) {
155  return ltrim(rtrim(s));
156 }
157 
158 std::vector<std::string> splitCSVLine(std::string &line){
159  std::vector<std::string> v;
160  std::stringstream ls(line);
161  std::string value;
162 
163  while(std::getline(ls, value, ',')) {
164  v.push_back(trim(value));
165  }
166  return v;
167 }
168 
169 void TemplateFilePage::BrowseParamsFile()
170 {
171  QSettings settings;
172  QString path;
173  if (settings.contains("last_params_file"))
174  path = settings.value("last_params_file").toString();
175  else
176  path = settings.value("workspace").toString();
177 
178  QString file = QFileDialog::getOpenFileName(this, "Browse", path);
179 
180  if (!QFile(file).exists())
181  return;
182 
183  try {
184 
185  std::ifstream fs(file.toStdString());
186  std::string line;
187  if (!std::getline(fs, line)) {
188  QMessageBox::critical(this, "Error", "First line of params file is invalid.", QMessageBox::Ok);
189  return;
190  }
191  m_params.clear();
192  m_param_names=splitCSVLine(line);
193 
194 
195  if (m_param_names.empty()) {
196  QMessageBox::critical(this, "Error", "First line of params file is invalid.", QMessageBox::Ok);
197  return;
198  }
199  int linecount=0;
200 
201  while (std::getline(fs, line)) {
202  std::vector<std::string> values=splitCSVLine(line);
203  linecount++;
204  if (values.empty())
205  continue;
206  if (values.size()!= m_param_names.size()) {
207  QMessageBox::critical(this, "Error", QString::fromStdString("Params file contains invalid input, line "+std::to_string(linecount)+"."), QMessageBox::Ok);
208  return;
209  }
210  m_params.push_back(values);
211  }
212 
213 
214  fs.close();
215 
216  } catch (std::exception& e) {
217  QMessageBox::critical(this, "Error", "Could not read file.", QMessageBox::Ok);
218  return;
219  } catch (...) {
220  QMessageBox::critical(this, "Error", "Unknown Exception", QMessageBox::Ok);
221  return;
222  }
223 
224  m_params_path->setText(file);
225  settings.setValue("last_params_file", file);
226 
227  emit completeChanged();
228 }
229 
230 bool TemplateFilePage::isComplete() const
231 {
232  return !m_ptree.empty();
233 }
234 
235 bool TemplateFilePage::validatePage()
236 {
237  std::vector<std::pair<std::string, ptree>> files;
238  std::map<std::string, int> param_map;
239  for(size_t i=0; i<m_param_names.size(); ++i ) {
240  param_map[m_param_names[i]]=i;
241  }
242 
243  int count=0;
244  for (auto param: m_params) {
245  ptree pt=m_ptree;
246 
247  std::function<void(ptree&)> iterate_over=[&iterate_over, &param, &param_map](ptree &p) -> void {
248  for (auto& child: p) {
249  if (child.second.empty()){
250  std::string value=trim(child.second.data());
251 
252  if (value.length()>1 && value[0]=='$' && value[value.length()-1]=='$') {
253  //This is a template value ($paramname$)
254  value=value.substr(1, value.length()-2);
255  auto found=param_map.find(value);
256 
257  if (found!=param_map.end()){
258  child.second.put_value(param[found->second]);
259  }
260  }
261  } else {
262  iterate_over(child.second);
263  }
264  }
265  };
266 
267  iterate_over(pt);
268  count++;
269 
270  files.push_back(std::make_pair("Param_"+std::to_string(count), pt));
271  }
272 
273  m_exploration = std::make_shared<FileExploration>("Untitled", files, m_preferences);
274  return true;
275 }
276 
277 } // namespace
Interface for TemplateFilePage.
Interface for RangeSweep.
Interface for ListSweep.
Namespace for SimPT parameter explorer package.
Definition: Client.cpp:52
Interface for ParameterExploration.
Interface for FileExploration.