root/src/xtalopt/testing/xtalopttest.cpp @ 9e95dd8ff05095921ecd2cd8790c9759bbb16155

Revision 9e95dd8ff05095921ecd2cd8790c9759bbb16155, 9.4 KB (checked in by David C. Lonie <loniedavid@…>, 13 months ago)

Added missing case values.

  • Property mode set to 100644
Line 
1/**********************************************************************
2  XtalOptTest - Automagically generate a ton of data from multiple runs
3
4  Copyright (C) 2009-2011 by David C. Lonie
5
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation version 2 of the License.
9
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14 ***********************************************************************/
15
16#include "xtalopttest.h"
17
18#include <xtalopt/xtalopt.h>
19#include <xtalopt/ui/dialog.h>
20
21#include <QtCore/QDebug>
22#include <QtCore/QFile>
23#include <QtCore/QTimer>
24#include <QtCore/QtConcurrentRun>
25
26#include <QtGui/QInputDialog>
27#include <QtGui/QProgressDialog>
28
29using namespace GlobalSearch;
30
31namespace XtalOpt {
32
33  XtalOptTest::XtalOptTest(XtalOpt *p, QObject *parent) :
34    QObject(parent),
35    m_opt(p),
36    m_dialog(qobject_cast<XtalOptDialog*>(p->dialog()))
37  {
38    connect(this, SIGNAL(testStarting()),
39            m_dialog, SLOT(lockGUI()),
40            Qt::BlockingQueuedConnection);
41    connect(this, SIGNAL(testStarting()),
42            m_dialog, SLOT(disconnectGUI()),
43            Qt::BlockingQueuedConnection);
44  }
45
46  XtalOptTest::~XtalOptTest()
47  {
48    m_prog->deleteLater();
49  }
50
51
52  void XtalOptTest::start()
53  {
54    emit testStarting();
55
56    // Prompt user for number of runs and structures
57    gatherData();
58
59    // Display progress dialog
60    showDialog();
61
62    // Start timer
63    m_begin = QDateTime::currentDateTime();
64
65    // Initialize dialog values
66    emit newMessage("Initializing test routine...");
67    emit status();
68
69    // Start optimization
70    emit newMessage("Running tests...");
71    for (int run = m_startRun; run <= m_endRun; run++) {
72      generateRun(run);
73      writeDataFile(run);
74    }
75  }
76
77  void XtalOptTest::gatherData() {
78    m_numberStructures = m_opt->test_nStructs;
79    m_startRun = m_opt->test_nRunsStart;
80    m_endRun = m_opt->test_nRunsEnd;
81    m_numberRuns = m_endRun - m_startRun + 1;
82    m_totalNumberStructures = m_numberStructures * m_numberRuns;
83  }
84
85  void XtalOptTest::showDialog() {
86    connect(this, SIGNAL(newMessage(const QString &)),
87            this, SLOT(updateMessage(const QString &)));
88    connect(this, SIGNAL(status()),
89            this, SLOT(updateStatus()));
90    connect(this, SIGNAL(sig_updateProgressDialog()),
91            this, SLOT(updateProgressDialog()));
92  }
93
94  void XtalOptTest::generateRun(int run) {
95    int m_currentStructure = 0;
96    int m_currentRun = run;
97    emit sig_updateProgressDialog();
98    // Perform run
99    emit status();
100    resetOpt();
101    m_opt->startSearch();
102    emit status();
103    m_message = "Looping...";
104    while (m_opt->tracker()->size() < m_numberStructures) {
105      //m_opt->queue()->checkPopulation();
106      //m_opt->queue()->checkRunning();
107      m_currentStructure = getCurrentStructure();
108      outputStatus(m_message,
109                   m_currentRun - m_startRun + 1,
110                   m_numberRuns,
111                   m_currentStructure,
112                   m_numberStructures,
113                   (m_currentRun-m_startRun) * m_numberStructures + m_currentStructure,
114                   m_totalNumberStructures);
115#ifdef WIN32
116      _sleep(1000);
117#else
118      sleep(1);
119#endif // _WIN32
120    }
121    m_message = "Waiting to finish...";
122    while (!isFinished()) {
123      //m_opt->queue()->checkPopulation();
124      //m_opt->queue()->checkRunning();
125      m_currentStructure = getCurrentStructure();
126      outputStatus(m_message,
127                   m_currentRun - m_startRun + 1,
128                   m_numberRuns,
129                   m_currentStructure,
130                   m_numberStructures,
131                   (m_currentRun-m_startRun) * m_numberStructures + m_currentStructure,
132                   m_totalNumberStructures);
133#ifdef WIN32
134      _sleep(1000);
135#else
136      sleep(1);
137#endif // _WIN32
138    }
139  }
140
141  bool XtalOptTest::isFinished() {
142    int done = 0;
143    m_opt->tracker()->lockForRead();
144    QList<Structure*> *structures = m_opt->tracker()->list();
145    Xtal* xtal = 0;
146    for (int i = 0; i < structures->size(); i++) {
147      xtal = qobject_cast<Xtal*>(structures->at(i));
148      xtal->lock()->lockForRead();
149      Xtal::State state = xtal->getStatus();
150      xtal->lock()->unlock();
151      if (state == Xtal::Optimized ||
152          state == Xtal::Killed ||
153          state == Xtal::Duplicate ||
154          state == Xtal::Removed)
155        done++;
156    }
157    m_opt->tracker()->unlock();
158    if (done >= m_numberStructures) return true;
159    else return false;
160  }
161
162  int XtalOptTest::getCurrentStructure() {
163    int n = 0;
164    m_opt->tracker()->lockForRead();
165    QList<Structure*> *structures = m_opt->tracker()->list();
166    Xtal* xtal = 0;
167    for (int i = 0; i < structures->size(); i++) {
168      xtal = qobject_cast<Xtal*>(structures->at(i));
169      xtal->lock()->lockForRead();
170      Xtal::State state = xtal->getStatus();
171      xtal->lock()->unlock();
172      if (state == Xtal::InProcess ||
173          state == Xtal::Optimized ||
174          state == Xtal::Submitted ||
175          state == Xtal::Killed ||
176          state == Xtal::Restart ||
177          state == Xtal::Duplicate ||
178          state == Xtal::Removed)
179        n++;
180    }
181    m_opt->tracker()->unlock();
182    return n;
183  }
184
185  void XtalOptTest::resetOpt() {
186    m_opt->reset();
187  }
188
189  void XtalOptTest::writeDataFile(int run) {
190    qDebug() << "Run " << run << " Finished!!" << endl;
191    QFile file;
192    file.setFileName(m_opt->filePath + "/run" +
193                     QString::number(run) + "-results.txt");
194    if (!file.open(QIODevice::WriteOnly)) {
195      m_opt->error("XtalOptTest::writeDataFile(): Error opening file "+file.fileName()+" for writing...");
196    }
197    QTextStream out;
198    out.setDevice(&file);
199    m_opt->tracker()->lockForRead();
200    QList<Structure*> *structures = m_opt->tracker()->list();
201    Xtal *xtal;
202
203    // Print the data to the file:
204    out << "Index\tGen\tID\tEnthalpy\tSpaceGroup\tStatus\tParentage\n";
205    for (int i = 0; i < structures->size(); i++) {
206      xtal = qobject_cast<Xtal*>(structures->at(i));
207      if (!xtal) continue; // In case there was a problem copying.
208      xtal->lock()->lockForRead();
209      out << i << "\t"
210          << xtal->getGeneration() << "\t"
211          << xtal->getIDNumber() << "\t"
212          << xtal->getEnthalpy() << "\t\t"
213          << xtal->getSpaceGroupNumber() << ": " << xtal->getSpaceGroupSymbol() << "\t\t";
214      // Status:
215      switch (xtal->getStatus()) {
216      case Xtal::Optimized:
217        out << "Optimized";
218        break;
219      case Xtal::Killed:
220      case Xtal::Removed:
221        out << "Killed";
222        break;
223      case Xtal::Duplicate:
224        out << "Duplicate";
225        break;
226      case Xtal::Error:
227        out << "Error";
228        break;
229      case Xtal::StepOptimized:
230      case Xtal::WaitingForOptimization:
231      case Xtal::InProcess:
232      case Xtal::Empty:
233      case Xtal::Updating:
234      case Xtal::Submitted:
235      case Xtal::Restart:
236      default:
237        out << "In progress";
238        break;
239      }
240      // Parentage:
241      out << "\t" << xtal->getParents();
242      xtal->lock()->unlock();
243      out << endl;
244    }
245    m_opt->tracker()->unlock();
246  }
247
248  void XtalOptTest::updateMessage(const QString & text) {
249    m_message = text;
250    emit sig_updateProgressDialog();
251  }
252
253  void XtalOptTest::updateStatus() {
254    emit sig_updateProgressDialog();
255  }
256
257  void XtalOptTest::updateProgressDialog() {
258  }
259
260  void XtalOptTest::outputStatus(const QString & message, int currentRun, int numberRuns, int currentStructure, int numberStructures, int totalStructures, int totalNumberStructures) {
261    int secondsElapsed = -QDateTime::currentDateTime().secsTo(m_begin);
262    double secondsPerStructure = secondsElapsed/double(totalStructures);
263    int remaining = int((totalNumberStructures - totalStructures) * secondsPerStructure);
264    int h = int(remaining / 3600);
265    remaining -= h*3600;
266    int m = int(remaining / 60);
267    remaining -= m*60;
268    int s = remaining;
269    QString remainingTime = QString("%1:%2:%3")
270      .arg(QString::number(h), 2, '0')
271      .arg(QString::number(m), 2, '0')
272      .arg(QString::number(s), 2, '0');
273    QString finishedAt = m_begin.addSecs(int(totalNumberStructures * secondsPerStructure)).toString("ddd, MMM dd hh:mm:ss");
274
275    qDebug() << "";
276    for (int i = 0; i < 2; i++) {
277      qDebug() << "-----------------------------------------------------------------------------------";
278    }
279    for (int i = 0; i < 2; i++) {
280      qDebug() << "###################################################################################";
281    }
282    qDebug() << tr("%1\nCurrent run: %2 of %3\nCurrent Structure: %4 of %5\nTotal Structures: %6 of %7")
283      .arg(message)
284      .arg(currentRun)
285      .arg(numberRuns)
286      .arg(currentStructure)
287      .arg(numberStructures)
288      .arg(totalStructures)
289      .arg(totalNumberStructures);
290    qDebug() << tr("%1 remaining, estimating finish at %2\ngiven the current rate of %3 seconds per structure.")
291      .arg(remainingTime).arg(finishedAt).arg(QString::number(secondsPerStructure));
292    for (int i = 0; i < 2; i++) {
293      qDebug() << "###################################################################################";
294    }
295    for (int i = 0; i < 2; i++) {
296      qDebug() << "-----------------------------------------------------------------------------------";
297    }
298    qDebug() << "";
299  }
300
301} // end namespace XtalOpt
Note: See TracBrowser for help on using the browser.