27 #include <boost/property_tree/exceptions.hpp>
28 #include <boost/property_tree/xml_parser.hpp>
30 #include <QDoubleValidator>
31 #include <QFileDialog>
32 #include <QFormLayout>
36 #include <QListWidget>
37 #include <QMessageBox>
38 #include <QPushButton>
39 #include <QRadioButton>
41 #include <QRegExpValidator>
44 #include <QVBoxLayout>
60 TemplateFilePage::TemplateFilePage(std::shared_ptr<Exploration> &exploration, boost::property_tree::ptree &preferences)
61 : m_exploration(exploration), m_preferences(preferences)
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.");
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...");
75 layout->addWidget(label);
76 layout->addWidget(m_file_path);
77 layout->addWidget(buttonBrowse);
78 mainlayout->addLayout(layout);
80 layout =
new QHBoxLayout;
82 QLabel* labelparams =
new QLabel(
"Params");
83 m_params_path =
new QLineEdit;
84 m_params_path->setReadOnly(
true);
85 QPushButton* buttonBrowseParams =
new QPushButton(
"Browse...");
87 layout->addWidget(labelparams);
88 layout->addWidget(m_params_path);
89 layout->addWidget(buttonBrowseParams);
91 mainlayout->addLayout(layout);
93 setLayout(mainlayout);
95 connect(buttonBrowse, SIGNAL(clicked()),
this, SLOT(BrowseLeafFile()));
96 connect(buttonBrowseParams, SIGNAL(clicked()),
this, SLOT(BrowseParamsFile()));
99 void TemplateFilePage::BrowseLeafFile()
104 if (settings.contains(
"last_template_file"))
105 path = settings.value(
"last_template_file").toString();
107 path = settings.value(
"workspace").toString();
109 QString file = QFileDialog::getOpenFileName(
this,
"Browse", path);
113 if (!QFile(file).exists())
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);
121 }
catch (ptree_bad_data& e) {
122 QMessageBox::critical(
this,
"Read Error",
"Error in file.", QMessageBox::Ok);
124 }
catch (xml_parser_error& e) {
125 QMessageBox::critical(
this,
"Error",
"Not a valid file.", QMessageBox::Ok);
127 }
catch (std::exception& e) {
128 QMessageBox::critical(
this,
"Error",
"Could not read file.", QMessageBox::Ok);
131 QMessageBox::critical(
this,
"Error",
"Unknown Exception", QMessageBox::Ok);
135 m_file_path->setText(file);
136 settings.setValue(
"last_template_file", file);
138 emit completeChanged();
142 static inline std::string <rim(std::string &s) {
143 s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
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());
154 static inline std::string &trim(std::string &s) {
155 return ltrim(rtrim(s));
158 std::vector<std::string> splitCSVLine(std::string &line){
159 std::vector<std::string> v;
160 std::stringstream ls(line);
163 while(std::getline(ls, value,
',')) {
164 v.push_back(trim(value));
169 void TemplateFilePage::BrowseParamsFile()
173 if (settings.contains(
"last_params_file"))
174 path = settings.value(
"last_params_file").toString();
176 path = settings.value(
"workspace").toString();
178 QString file = QFileDialog::getOpenFileName(
this,
"Browse", path);
180 if (!QFile(file).exists())
185 std::ifstream fs(file.toStdString());
187 if (!std::getline(fs, line)) {
188 QMessageBox::critical(
this,
"Error",
"First line of params file is invalid.", QMessageBox::Ok);
192 m_param_names=splitCSVLine(line);
195 if (m_param_names.empty()) {
196 QMessageBox::critical(
this,
"Error",
"First line of params file is invalid.", QMessageBox::Ok);
201 while (std::getline(fs, line)) {
202 std::vector<std::string> values=splitCSVLine(line);
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);
210 m_params.push_back(values);
216 }
catch (std::exception& e) {
217 QMessageBox::critical(
this,
"Error",
"Could not read file.", QMessageBox::Ok);
220 QMessageBox::critical(
this,
"Error",
"Unknown Exception", QMessageBox::Ok);
224 m_params_path->setText(file);
225 settings.setValue(
"last_params_file", file);
227 emit completeChanged();
230 bool TemplateFilePage::isComplete()
const
232 return !m_ptree.empty();
235 bool TemplateFilePage::validatePage()
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;
244 for (
auto param: m_params) {
247 std::function<void(ptree&)> iterate_over=[&iterate_over, ¶m, ¶m_map](ptree &p) ->
void {
248 for (
auto& child: p) {
249 if (child.second.empty()){
250 std::string value=trim(child.second.data());
252 if (value.length()>1 && value[0]==
'$' && value[value.length()-1]==
'$') {
254 value=value.substr(1, value.length()-2);
255 auto found=param_map.find(value);
257 if (found!=param_map.end()){
258 child.second.put_value(param[found->second]);
262 iterate_over(child.second);
270 files.push_back(std::make_pair(
"Param_"+std::to_string(count), pt));
273 m_exploration = std::make_shared<FileExploration>(
"Untitled", files, m_preferences);
Interface for TemplateFilePage.
Interface for RangeSweep.
Namespace for SimPT parameter explorer package.
Interface for ParameterExploration.
Interface for FileExploration.