DCSConfigEditorDisplay.cpp
Go to the documentation of this file.
1 #include <DatabaseUtils/GUI/DCSConfigEditorDisplay.h>
2 #include <DatabaseUtils/DAQConfig/GlobalNameSpec.h>
3 #include <DatabaseUtils/DAQConfig/NamedConfigUtils.h>
4 #include <NovaDAQUtilities/EnvVarCache.h>
5 #include <boost/shared_ptr.hpp>
6 #include <QtCore/QCoreApplication>
7 #include <QtCore/QProcess>
8 #include <QtGui/QVBoxLayout>
9 #include <QtGui/QInputDialog>
10 #include <QtGui/QMenu>
11 #include <QtGui/QMenuBar>
12 #include <QtGui/QMessageBox>
13 #include <QtGui/QProgressDialog>
14 #include <QtGui/QPushButton>
15 #include <QtGui/QFileDialog>
16 #include <boost/assign/std/vector.hpp> // for 'operator+=()'
17 #include <boost/filesystem.hpp>
18 
19 using namespace boost::assign; // bring 'operator+=()' into scope
20 using namespace dbutils::daqconfig;
21 
22 namespace BFS = boost::filesystem;
23 
24 namespace dbutils {
25 namespace gui {
26 
27 DCSConfigEditorDisplay::
28 DCSConfigEditorDisplay(QWidget *parent) : BasicEditorDisplay(parent)
29 {
30  std::string detectorString =
31  novadaq::EnvVarCache::getInstance().getEnvVar("NOVADAQ_ENVIRONMENT");
32  if (detectorString.length() == 0) {
33  detectorString = "NOVADAQ_ENVIRONMENT_EnvVar_NeedsToBeSet";
34  }
35 
36  _pvScriptOutputDir = "/nova/config/" + detectorString + "/DCS";
37 
38  // (hopefully) temporary menu option to call the script that
39  // converts the DB entries into PV settings
40  QMenu* actionMenu = menuBar()->addMenu(tr("&Action"));
41  QAction* genScriptAction =
42  actionMenu->addAction(tr("&Generate Recipe Scripts"));
43  QObject::connect(genScriptAction, SIGNAL(triggered()),
44  this, SLOT(generateRecipeScripts()));
45 
46  QAction* loadHVAndTempsAction =
47  actionMenu->addAction(tr("&Load HV and Temperatures"));
48  QObject::connect(loadHVAndTempsAction, SIGNAL(triggered()),
49  this, SLOT(loadHVAndTemps()));
50 
51  _addHelpMenu();
52 
53  std::vector<std::string> tableDefinitions;
54  tableDefinitions +=
55  "NovaDatabase/tables/DCS/DCSFEBEnableMasks.xml",
56  "NovaDatabase/tables/DCS/APDTemperatureSettings.xml",
57  "NovaDatabase/tables/DCS/APDHighVoltages.xml",
58  "NovaDatabase/tables/DCS/FEBDryAirChannels.xml",
59  "NovaDatabase/tables/DCS/EPICSAlarmThresholds.xml";
60 
62  reset(new GlobalNameSpec("ColdDetectorSettings", "DCS",
63  detectorString));
64  _globalNameSpecPtr->isSlowControlsConfiguration(true);
66  if (! NamedConfigUtils::getGlobalConfigId((*_globalNameSpecPtr),
68  std::cerr << "Error fetching globalConfigId." << std::endl;
69  }
70  IDSpec idSpec(_currentGlobalConfigId, IDSpec::GLOBAL,
71  (_globalNameSpecPtr->isSlowControlsConfiguration() ?
72  IDSpec::SLOWCONTROLS : IDSpec::DAQ));
73 
74  _editorSet = new TabbedSetOfTreeEditors("APDHardware", "slowcontrols",
75  tableDefinitions,this);
76  _editorSet->isTopLevel(true);
77  _editorSet->loadData(idSpec);
78  connect(_editorSet, SIGNAL(aChangeWasMade()),
79  this, SLOT(reactToDataChange()));
80  connect(_editorSet, SIGNAL(dataWasSaved()),
81  this, SLOT(reactToDataSave()));
82 
85 
86  QVBoxLayout* thisDisplayLayout = new QVBoxLayout;
87  thisDisplayLayout->addWidget(_editorSet);
88  thisDisplayLayout->addWidget(_settingsDisplay);
89  QWidget* tmpWidget = new QWidget();
90  tmpWidget->setContentsMargins(0,5,0,0);
91  tmpWidget->setLayout(thisDisplayLayout);
92 
93  setCentralWidget(tmpWidget);
94 }
95 
97 {
98  return _editorSet->hasChanges();
99 }
100 
102 {
103  // check that the user really wants to do this
104  std::string dbString =
106  QMessageBox confirmBox(this);
107 
108  std::string msgText = "You are about to update PV scripts on ";
109  msgText.append("disk based on data in the \"");
110  msgText.append(dbString);
111  msgText.append("\" database.");
112  confirmBox.setText(msgText.c_str());
113 
114  msgText = "Are you sure that you want to re-generate ";
115  msgText.append("the PV settings scripts?");
116  confirmBox.setInformativeText(msgText.c_str());
117 
118  confirmBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
119  confirmBox.setDefaultButton(QMessageBox::No);
120  int retCode = confirmBox.exec();
121 
122  if (retCode != QMessageBox::Yes) {return;}
123 
124  // determine the output directory to use
125  bool status;
126  QString responseText =
127  QInputDialog::getText(this, tr("Output directory"),
128  tr("Enter the output directory for the generated PV scripts:"),
130  _pvScriptOutputDir.c_str(), &status);
131  if (! status) {return;}
132  _pvScriptOutputDir = responseText.toStdString();
133 
134  // verify that the specified output directory is valid
135  if (! BFS::exists(_pvScriptOutputDir)) {
136  std::string msgText = "Output directory ";
137  msgText.append(_pvScriptOutputDir);
138  msgText.append(" does not exist. Aborting script generation...");
139  QMessageBox::critical(this, "Invalid Output Directory", msgText.c_str());
140  return;
141  }
142 
143  // generate the scripts
144  QProgressDialog progressBar("Generating scripts... Timeout at 100%", "Close", 0, 10, this);
145  progressBar.setWindowModality(Qt::WindowModal);
146  progressBar.setMinimumDuration(0);
147  progressBar.setValue(0);
148  QCoreApplication::processEvents(QEventLoop::AllEvents, 500);
149 
150  std::string cmd = "GenerateDCSRecipeScripts.sh ";
151  cmd.append(_pvScriptOutputDir);
152  boost::shared_ptr<QProcess> processPtr(new QProcess(this));
153  processPtr->start(cmd.c_str());
154 
155  bool finished = false;
156  QCoreApplication::processEvents(QEventLoop::AllEvents, 500);
157  if (processPtr->waitForStarted(8000)) {
158  progressBar.setValue(1);
159  QCoreApplication::processEvents(QEventLoop::AllEvents, 500);
160  for (int idx = 2; idx < 15; ++idx) {
161  if (processPtr->waitForFinished(8000)) {
162  finished = true;
163  break;
164  }
165  progressBar.setValue(idx < 9 ? idx : 9);
166  QCoreApplication::processEvents(QEventLoop::AllEvents, 500);
167  }
168  }
169  progressBar.setValue(10);
170  QCoreApplication::processEvents(QEventLoop::AllEvents, 500);
171 
172  if (! finished) {
173  processPtr->kill();
174  processPtr->waitForFinished(5000);
175  }
176 
177  std::string stdoutString(processPtr->readAllStandardOutput());
178  std::string stderrString(processPtr->readAllStandardError());
179 
180  if (finished) {
181  std::string msgText = "The job to generated the PV ";
182  msgText.append("settings scripts completed ");
183  msgText.append("Press \"Show Details...\" to see output.");
184  std::string outText = stdoutString;
185  outText.append("\n");
186  outText.append(stderrString);
187  QMessageBox resultBox(this);
188  resultBox.setIcon(QMessageBox::Information);
189  resultBox.setWindowTitle("PV Script Result");
190  resultBox.setText(msgText.c_str());
191  resultBox.setDetailedText(outText.c_str());
192  resultBox.exec();
193  //QMessageBox::information(this, "PV Script Result", msgText.c_str());
194  }
195  else {
196  std::string msgText = "The job to generated the PV ";
197  msgText.append("settings scripts timed out. ");
198  msgText.append("Press \"Show Details...\" to see output.");
199 
200  std::string outText = stdoutString;
201  outText.append("\n");
202  outText.append(stderrString);
203  QMessageBox resultBox(this);
204  resultBox.setIcon(QMessageBox::Warning);
205  resultBox.setWindowTitle("PV Script Result");
206  resultBox.setText(msgText.c_str());
207  resultBox.setDetailedText(outText.c_str());
208  resultBox.exec();
209  //QMessageBox::warning(this, "PV Script Result", msgText.c_str());
210  }
211 }
212 
215 {
216  return _editorSet->loadData(idSpec);
217 }
218 
221 {
222  return _editorSet->loadData(idSpec);
223 }
224 
227  const dbutils::daqconfig::IDSpec& newIdSpec,
228  const dbutils::daqconfig::GlobalNameSpec& newNameSpec)
229 {
230  return _editorSet->saveChanges(oldIdSpec, newIdSpec, newNameSpec);
231 }
232 
233 
235 {
236  ///////////////////////////////////
237  // Prompt for location of the csv
238  std::string detName=_globalNameSpecPtr->getDetectorName();
239  std::string detDir;
240  if(detName=="FarDet")
241  detDir = "";
242  else if(detName=="NDOS")
243  detDir = "";
244  else if(detName=="NearDet")
245  detDir = "";
246  else if(detName=="NDSBTest")
247  detDir = "";
248  else
249  detDir = "";
250 
251  QFileDialog peddialog(this);
252  peddialog.setViewMode(QFileDialog::Detail);
253  QString folderName = peddialog.getExistingDirectory(this, tr("Select HV/Temp Directory."),
254  detDir.c_str(),
255  QFileDialog::ShowDirsOnly|QFileDialog::DontUseNativeDialog);
256  if(folderName==""){return;}
257 
258  /////////////////////////////////
259  // DB load confirmation box
260  QMessageBox confirmBox(this);
261  int count;
262  std::ostringstream hvfebs;
263  std::ostringstream tempfebs;
264 
265  boost::filesystem::path p(folderName.toUtf8().constData());
266  boost::filesystem::path uniquestamp = p.filename();
267 
268  std::string hvFileName = folderName.toUtf8().constData();
269  hvFileName.append("/hv_");
270  hvFileName.append(uniquestamp.string());
271  hvFileName.append(".csv");
272  std::string tempFileName = folderName.toUtf8().constData();
273  tempFileName.append("/temp_");
274  tempFileName.append(uniquestamp.string());
275  tempFileName.append(".csv");
276 
277 
278  std::ifstream hvFile(hvFileName.c_str());
279  count=std::count(std::istreambuf_iterator<char>(hvFile),
280  std::istreambuf_iterator<char>(), '\n');
281  hvfebs << count;
282 
283  std::ifstream tempFile(tempFileName.c_str());
284  count=std::count(std::istreambuf_iterator<char>(tempFile),
285  std::istreambuf_iterator<char>(), '\n');
286  tempfebs << count;
287 
288  std::string msgText = "You are about to load voltages and temperatures from ";
289  msgText.append(folderName.toUtf8().constData());
290  msgText.append("\n\n Found voltage results from ");
291  msgText.append(hvfebs.str());
292  msgText.append(" febs, temperature results from ");
293  msgText.append(tempfebs.str());
294  msgText.append(" febs.");
295  confirmBox.setText(msgText.c_str());
296 
297  msgText = "Are you sure that you want to load these values? ";
298  confirmBox.setInformativeText(msgText.c_str());
299  confirmBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
300  confirmBox.setDefaultButton(QMessageBox::No);
301  int retCode = confirmBox.exec();
302  if (retCode != QMessageBox::Yes) {return;}
303 
304  //////////
305  // Ask if user want to overide all setting in the config or simply append
306  // apply proper defualts if they want to override
307  QMessageBox loadBox(this);
308  msgText = "Do you want to override ALL existing exceptions underneath the defaults or append the results?";
309  loadBox.setText(msgText.c_str());
310  loadBox.addButton(tr("Override"),QMessageBox::AcceptRole);
311  loadBox.addButton(tr("Append"),QMessageBox::NoRole);
312  loadBox.addButton(QMessageBox::Cancel);
313  loadBox.setDefaultButton(QMessageBox::Cancel);
314  retCode = loadBox.exec();
315  std::string configName = _globalNameSpecPtr->getConfigName();
316 
317  std::string systemCommand = "LoadAPDHighVoltagesAndTemps NovaDatabase/tables/DCS ";
318  if (retCode == QMessageBox::Cancel){return;}
319  else if (retCode == QMessageBox::AcceptRole) {
320  std::string tmpstring;
321  tmpstring = folderName.toUtf8().constData();
322  tmpstring.append("/hvXXXXXX");
323  char *hvTmpName = new char[tmpstring.length() + 1];
324  strcpy(hvTmpName, tmpstring.c_str()); // Get temp name
325 
326  tmpstring = folderName.toUtf8().constData();
327  tmpstring.append("/tempXXXXXX");
328  char *tempTmpName = new char[tmpstring.length() + 1]; // Get temp name
329  strcpy(tempTmpName, tmpstring.c_str()); // Get temp name
330 
331 
332  mkstemp(hvTmpName);
333  mkstemp(tempTmpName);
334 
335  FILE * hvFileTmp = fopen (hvTmpName, "w");
336  FILE * tempFileTmp = fopen (tempTmpName, "w");
337 
338  std::string systemCommandtmp = "";
339 
340  //defaults
341  fputs ("1,default,-1,cold,1533,0,1,2,3,4\n", hvFileTmp);
342  fputs ("1,default,-1,warm,2957,0,1,2,3,4\n", hvFileTmp);
343  fputs ("1,default,-1,2000,0,1,2,3,4\n",tempFileTmp);
344  fclose(hvFileTmp);
345  fclose(tempFileTmp);
346 
347  systemCommandtmp.append(systemCommand);
348  systemCommandtmp.append(hvTmpName);
349  systemCommandtmp.append(" ");
350  systemCommandtmp.append(tempTmpName);
351  systemCommandtmp.append(" ");
352  systemCommandtmp.append(configName);
353  system(systemCommandtmp.c_str());
354 
355  remove(hvTmpName);
356  remove(tempTmpName);
357  }
358 
359  /////////////////////////////////
360  // Prompt user with status ans load into the database
361  //#Output the database environment
362  //echo
363  //echo 'Loading into' $NOVADBNAME 'on' $NOVADBHOST 'at port' $NOVADBPORT '....'
364 
365  //#Load the Thesholds and Masks
366 
367  systemCommand.append(hvFileName);
368  systemCommand.append(" ");
369  systemCommand.append(tempFileName);
370  systemCommand.append(" ");
371  systemCommand.append(configName);
372  std::cout<<systemCommand.c_str()<<std::endl;
373  system(systemCommand.c_str());
374 
375  ///////////////////////////////
376  //Refresh the editor
378 
379 } // end of loadHVAndTemps
380 
381 } // end of namespace gui
382 } // end of namespace dbutils
383 
def progressBar(value, endvalue, docdb_id, bar_length=40)
Definition: bp_utils.py:6
system("rm -rf microbeam.root")
int status
Definition: fabricate.py:1613
const char * p
Definition: xmltok.h:285
static EnvVarCache & getInstance()
Definition: EnvVarCache.cpp:12
OStream cerr
Definition: OStream.cxx:7
bool _doReloadCurrentDataset(const dbutils::daqconfig::IDSpec &idSpec)
void updateNamedConfiguration(const dbutils::daqconfig::GlobalNameSpec &nameSpec)
void _addHelpMenu(std::string customText="")
def connect(endpoint="tcp://127.0.0.1:5555")
Definition: g4zmq.py:15
fclose(fg1)
string cmd
Definition: run_hadd.py:52
boost::shared_ptr< dbutils::daqconfig::GlobalNameSpec > _globalNameSpecPtr
bool loadData(const dbutils::daqconfig::IDSpec &idSpec)
OStream cout
Definition: OStream.cxx:6
const std::string path
Definition: plot_BEN.C:43
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
std::string getEnvVar(std::string name)
Definition: EnvVarCache.cpp:33
bool saveChanges(const dbutils::daqconfig::IDSpec &oldGlobalIdSpec, const dbutils::daqconfig::IDSpec &newGlobalIdSpec, const dbutils::daqconfig::GlobalNameSpec &newGlobalNameSpec)
bool _doLoadNewDataset(const dbutils::daqconfig::IDSpec &idSpec)
detName
Definition: mkDefs.py:106
bool _doSaveChanges(const dbutils::daqconfig::IDSpec &oldIdSpec, const dbutils::daqconfig::IDSpec &newIdSpec, const dbutils::daqconfig::GlobalNameSpec &newNameSpec)