source: src/controller.cpp@ 9dcce3

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 Candidate_v1.7.0 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 9dcce3 was 9dcce3, checked in by Frederik Heber <heber@…>, 13 years ago

Refactored parsing of command line parameters into structure ControllerOptions.

  • this structure can be derived from to add other parsing functions and options.
  • Property mode set to 100644
File size: 20.1 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2011 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * \file controller.cpp
10 *
11 * This file strongly follows the Serialization example from the boost::asio
12 * library (see client.cpp)
13 *
14 * Created on: Nov 27, 2011
15 * Author: heber
16 */
17
18
19// include config.h
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24// boost asio needs specific operator new
25#include <boost/asio.hpp>
26
27#include "CodePatterns/MemDebug.hpp"
28
29#include <boost/archive/text_oarchive.hpp>
30#include <boost/archive/text_iarchive.hpp>
31#include <boost/program_options.hpp>
32#include <fstream>
33#include <iostream>
34#include <map>
35#include <sstream>
36#include <streambuf>
37#include <vector>
38
39#include "Fragmentation/Automation/atexit.hpp"
40#include "CodePatterns/Info.hpp"
41#include "CodePatterns/Log.hpp"
42#include "Fragmentation/EnergyMatrix.hpp"
43#include "Fragmentation/ForceMatrix.hpp"
44#include "Fragmentation/KeySetsContainer.hpp"
45#include "FragmentController.hpp"
46#include "Helpers/defs.hpp"
47#include "Jobs/MPQCCommandJob.hpp"
48#include "Jobs/MPQCCommandJob_MPQCData.hpp"
49#include "Fragmentation/Automation/Jobs/SystemCommandJob.hpp"
50#include "Fragmentation/Automation/Results/FragmentResult.hpp"
51
52enum CommandIndices {
53 UnknownCommandIndex = 0,
54 AddJobsIndex = 1,
55 CreateJobsIndex = 2,
56 CheckResultsIndex = 3,
57 ReceiveResultsIndex = 4,
58 ReceiveMPQCIndex = 5,
59 RemoveAllIndex = 6,
60 ShutdownIndex = 7,
61};
62
63
64/** Creates a SystemCommandJob out of give \a command with \a argument.
65 *
66 * @param jobs created job is added to this vector
67 * @param command command to execute for SystemCommandJob
68 * @param argument argument for command to execute
69 * @param nextid id for this job
70 */
71void createjobs(
72 std::vector<FragmentJob::ptr> &jobs,
73 const std::string &command,
74 const std::string &argument,
75 const JobId_t nextid)
76{
77
78 FragmentJob::ptr testJob( new SystemCommandJob(command, argument, nextid) );
79 jobs.push_back(testJob);
80 LOG(1, "INFO: Added one SystemCommandJob.");
81}
82
83/** Creates a MPQCCommandJob with argument \a filename.
84 *
85 * @param jobs created job is added to this vector
86 * @param command mpqc command to execute
87 * @param filename filename being argument to job
88 * @param nextid id for this job
89 */
90void parsejob(
91 std::vector<FragmentJob::ptr> &jobs,
92 const std::string &command,
93 const std::string &filename,
94 const JobId_t nextid)
95{
96 std::ifstream file;
97 file.open(filename.c_str());
98 ASSERT( file.good(), "parsejob() - file "+filename+" does not exist.");
99 std::string output((std::istreambuf_iterator<char>(file)),
100 std::istreambuf_iterator<char>());
101 FragmentJob::ptr testJob( new MPQCCommandJob(output, nextid, command) );
102 jobs.push_back(testJob);
103 file.close();
104 LOG(1, "INFO: Added MPQCCommandJob from file "+filename+".");
105}
106
107/** Print received results.
108 *
109 * @param results received results to print
110 */
111void printReceivedResults(std::vector<FragmentResult::ptr> &results)
112{
113 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
114 iter != results.end(); ++iter)
115 LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
116}
117
118/** Print MPQCData from received results.
119 *
120 * @param results received results to extract MPQCData from
121 * @param KeySetFilename filename with keysets to associate forces correctly
122 * @param NoAtoms total number of atoms
123 */
124bool printReceivedMPQCResults(
125 const std::vector<FragmentResult::ptr> &results,
126 const std::string &KeySetFilename,
127 size_t NoAtoms)
128{
129 EnergyMatrix Energy;
130 EnergyMatrix EnergyFragments;
131 ForceMatrix Force;
132 ForceMatrix ForceFragments;
133 KeySetsContainer KeySet;
134
135 // align fragments
136 std::map< JobId_t, size_t > MatrixNrLookup;
137 size_t FragmentCounter = 0;
138 {
139 // bring ids in order ...
140 typedef std::map< JobId_t, FragmentResult::ptr> IdResultMap_t;
141 IdResultMap_t IdResultMap;
142 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
143 iter != results.end(); ++iter) {
144 #ifndef NDEBUG
145 std::pair< IdResultMap_t::iterator, bool> inserter =
146 #endif
147 IdResultMap.insert( make_pair((*iter)->getId(), *iter) );
148 ASSERT( inserter.second,
149 "printReceivedMPQCResults() - two results have same id "
150 +toString((*iter)->getId())+".");
151 }
152 // ... and fill lookup
153 for(IdResultMap_t::const_iterator iter = IdResultMap.begin();
154 iter != IdResultMap.end(); ++iter)
155 MatrixNrLookup.insert( make_pair(iter->first, FragmentCounter++) );
156 }
157 LOG(1, "INFO: There are " << FragmentCounter << " fragments.");
158
159 // extract results
160 std::vector<MPQCData> fragmentData(results.size());
161 MPQCData combinedData;
162
163 LOG(2, "DEBUG: Parsing now through " << results.size() << " results.");
164 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
165 iter != results.end(); ++iter) {
166 LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
167 MPQCData extractedData;
168 std::stringstream inputstream((*iter)->result);
169 LOG(2, "DEBUG: First 50 characters FragmentResult's string: "+(*iter)->result.substr(0, 50));
170 boost::archive::text_iarchive ia(inputstream);
171 ia >> extractedData;
172 LOG(1, "INFO: extracted data is " << extractedData << ".");
173
174 // place results into EnergyMatrix ...
175 {
176 MatrixContainer::MatrixArray matrix;
177 matrix.resize(1);
178 matrix[0].resize(1, extractedData.energy);
179 if (!Energy.AddMatrix(
180 std::string("MPQCJob ")+toString((*iter)->getId()),
181 matrix,
182 MatrixNrLookup[(*iter)->getId()])) {
183 ELOG(1, "Adding energy matrix failed.");
184 return false;
185 }
186 }
187 // ... and ForceMatrix (with two empty columns in front)
188 {
189 MatrixContainer::MatrixArray matrix;
190 const size_t rows = extractedData.forces.size();
191 matrix.resize(rows);
192 for (size_t i=0;i<rows;++i) {
193 const size_t columns = 2+extractedData.forces[i].size();
194 matrix[i].resize(columns, 0.);
195 // for (size_t j=0;j<2;++j)
196 // matrix[i][j] = 0.;
197 for (size_t j=2;j<columns;++j)
198 matrix[i][j] = extractedData.forces[i][j-2];
199 }
200 if (!Force.AddMatrix(
201 std::string("MPQCJob ")+toString((*iter)->getId()),
202 matrix,
203 MatrixNrLookup[(*iter)->getId()])) {
204 ELOG(1, "Adding force matrix failed.");
205 return false;
206 }
207 }
208 }
209 // add one more matrix (not required for energy)
210 MatrixContainer::MatrixArray matrix;
211 matrix.resize(1);
212 matrix[0].resize(1, 0.);
213 if (!Energy.AddMatrix(std::string("MPQCJob total"), matrix, FragmentCounter))
214 return false;
215 // but for energy because we need to know total number of atoms
216 matrix.resize(NoAtoms);
217 for (size_t i = 0; i< NoAtoms; ++i)
218 matrix[i].resize(2+NDIM, 0.);
219 if (!Force.AddMatrix(std::string("MPQCJob total"), matrix, FragmentCounter))
220 return false;
221
222
223 // combine all found data
224 if (!Energy.InitialiseIndices()) return false;
225
226 if (!Force.ParseIndices(KeySetFilename.c_str())) return false;
227
228 if (!KeySet.ParseKeySets(KeySetFilename.c_str(), Force.RowCounter, Force.MatrixCounter)) return false;
229
230 if (!KeySet.ParseManyBodyTerms()) return false;
231
232 if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return false;
233 if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return false;
234
235 if(!Energy.SetLastMatrix(0., 0)) return false;
236 if(!Force.SetLastMatrix(0., 2)) return false;
237
238 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
239 // --------- sum up energy --------------------
240 LOG(1, "INFO: Summing energy of order " << BondOrder+1 << " ...");
241 if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return false;
242 if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return false;
243
244 // --------- sum up Forces --------------------
245 LOG(1, "INFO: Summing forces of order " << BondOrder+1 << " ...");
246 if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return false;
247 if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return false;
248 }
249
250 // for debugging print resulting energy and forces
251 LOG(1, "INFO: Resulting energy is " << Energy.Matrix[ FragmentCounter ][0][0]);
252 std::stringstream output;
253 for (int i=0; i< Force.RowCounter[FragmentCounter]; ++i) {
254 for (int j=0; j< Force.ColumnCounter[FragmentCounter]; ++j)
255 output << Force.Matrix[ FragmentCounter ][i][j] << " ";
256 output << "\n";
257 }
258 LOG(1, "INFO: Resulting forces are " << std::endl << output.str());
259
260 return true;
261}
262
263/** Helper function to get number of atoms somehow.
264 *
265 * Here, we just parse the number of lines in the adjacency file as
266 * it should correspond to the number of atoms, except when some atoms
267 * are not bonded, but then fragmentation makes no sense.
268 *
269 * @param path path to the adjacency file
270 */
271size_t getNoAtomsFromAdjacencyFile(const std::string &path)
272{
273 size_t NoAtoms = 0;
274
275 // parse in special file to get atom count (from line count)
276 std::string filename(path);
277 filename += FRAGMENTPREFIX;
278 filename += ADJACENCYFILE;
279 std::ifstream adjacency(filename.c_str());
280 if (adjacency.fail()) {
281 LOG(0, endl << "getNoAtomsFromAdjacencyFile() - Unable to open " << filename << ", is the directory correct?");
282 return false;
283 }
284 std::string buffer;
285 while (getline(adjacency, buffer))
286 NoAtoms++;
287 LOG(1, "INFO: There are " << NoAtoms << " atoms.");
288
289 return NoAtoms;
290}
291
292
293/** Returns a unique index for every command to allow switching over it.
294 *
295 * \param &commandmap map with command strings
296 * \param &cmd command string
297 * \return index from CommandIndices: UnkownCommandIndex - unknown command, else - command index
298 */
299CommandIndices getCommandIndex(std::map<std::string, CommandIndices> &commandmap, const std::string &cmd)
300{
301 std::map<std::string, CommandIndices>::const_iterator iter = commandmap.find(cmd);
302 if (iter != commandmap.end())
303 return iter->second;
304 else
305 return UnknownCommandIndex;
306}
307
308struct ControllerOptions
309{
310 int parseHelp(boost::program_options::variables_map &vm, const boost::program_options::options_description &desc) {
311 if (vm.count("help")) {
312 std::cout << desc << "\n";
313 return 1;
314 }
315 return 0;
316 }
317 int parseVerbosity(boost::program_options::variables_map &vm) {
318 if (vm.count("verbosity")) {
319 LOG(0, "STATUS: Verbosity level was set to " << vm["verbosity"].as<size_t>() << ".");
320 setVerbosity(vm["verbosity"].as<size_t>());
321 } else {
322 LOG(0, "STATUS: Verbosity level was not set, defaulting to 5.");
323 setVerbosity(5);
324 }
325 return 0;
326 }
327
328 int parseServerPort(boost::program_options::variables_map &vm) {
329 if (vm.count("server")) {
330 server = vm["server"].as< std::string >();
331 serverport = server.substr(server.find_last_of(':')+1, std::string::npos);
332 server = server.substr(0, server.find_last_of(':'));
333 try {
334 boost::lexical_cast<size_t>(serverport);
335 } catch (boost::bad_lexical_cast &) {
336 ELOG(1, "Could not interpret " << serverport << " as server:port.");
337 return 255;
338 }
339 LOG(1, "INFO: Using " << server << ":" << serverport << " as server's address.");
340 } else {
341 ELOG(1, "Requiring server's address (host:port) to connect to.");
342 return 255;
343 }
344 return 0;
345 }
346
347 int parseCommand(boost::program_options::variables_map &vm, const std::vector<std::string> &Commands) {
348 if (!vm.count("command")) {
349 ELOG(1, "Controller requires one of the following commands: "+toString(Commands));
350 return 255;
351 }
352 command = vm["command"].as< std::string >();
353 return 0;
354 }
355
356 std::string command;
357 std::string server;
358 std::string serverport;
359
360};
361
362struct ControllerOptions_SystemCommandJob : public ControllerOptions
363{
364 int parseExecutable(boost::program_options::variables_map &vm) {
365 if ((command == "createjobs") || (command == "addjobs")) {
366 if (!vm.count("executable")) {
367 ELOG(1, "'"+command+"' requires two options: [executable] [jobcommand].");
368 return 255;
369 }
370 executable = vm["executable"].as< std::string >();
371 }
372 return 0;
373 }
374
375 int parseJobCommand(boost::program_options::variables_map &vm) {
376 if (command == "createjobs") {
377 if (!vm.count("jobcommand")) {
378 ELOG(1, "'"+command+"' requires two options: [executable] [jobcommand].");
379 return 255;
380 }
381 jobcommand = vm["jobcommand"].as< std::string >();
382 }
383 return 0;
384 }
385
386 std::string executable;
387 std::string jobcommand;
388};
389
390int main(int argc, char* argv[])
391{
392 // from this moment on, we need to be sure to deeinitialize in the correct order
393 // this is handled by the cleanup function
394 atexit(cleanUp);
395
396 setVerbosity(3);
397
398 size_t Exitflag = 0;
399 typedef std::map<std::string, CommandIndices> CommandsMap_t;
400 CommandsMap_t CommandsMap;
401 CommandsMap.insert( std::make_pair("addjobs", AddJobsIndex) );
402 CommandsMap.insert( std::make_pair("createjobs", CreateJobsIndex) );
403 CommandsMap.insert( std::make_pair("checkresults", CheckResultsIndex) );
404 CommandsMap.insert( std::make_pair("receiveresults", ReceiveResultsIndex) );
405 CommandsMap.insert( std::make_pair("receivempqc", ReceiveMPQCIndex) );
406 CommandsMap.insert( std::make_pair("removeall", RemoveAllIndex) );
407 CommandsMap.insert( std::make_pair("shutdown", ShutdownIndex) );
408 std::vector<std::string> Commands;
409 for (CommandsMap_t::const_iterator iter = CommandsMap.begin(); iter != CommandsMap.end(); ++iter)
410 Commands.push_back(iter->first);
411
412 // Declare the supported options.
413 boost::program_options::options_description desc("Allowed options");
414 desc.add_options()
415 ("help,h", "produce help message")
416 ("verbosity,v", boost::program_options::value<size_t>(), "set verbosity level")
417 ("server", boost::program_options::value< std::string >(), "connect to server at this address (host:port)")
418 ("command", boost::program_options::value< std::string >(), (std::string("command to send to server: ")+toString(Commands)).c_str())
419 ("executable", boost::program_options::value< std::string >(), "executable for commands 'addjobs' and 'createjobs'")
420 ("fragment-path", boost::program_options::value< std::string >(), "path to fragment files for 'receivempqcresults'")
421 ("jobcommand", boost::program_options::value< std::string >(), "command argument for executable for 'createjobs'")
422 ("jobfiles", boost::program_options::value< std::vector< std::string > >()->multitoken(), "list of files as single argument to executable for 'addjobs'")
423 ;
424
425 boost::program_options::variables_map vm;
426 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
427 boost::program_options::notify(vm);
428 ControllerOptions_SystemCommandJob ControllerInfo;
429
430 ControllerInfo.parseHelp(vm, desc);
431
432 ControllerInfo.parseVerbosity(vm);
433
434 ControllerInfo.parseServerPort(vm);
435
436 ControllerInfo.parseCommand(vm, Commands);
437 const CommandIndices commandIndex = getCommandIndex(CommandsMap, ControllerInfo.command);
438
439 ControllerInfo.parseExecutable(vm);
440
441 ControllerInfo.parseJobCommand(vm);
442
443 // check arguments
444 switch(commandIndex) {
445 case AddJobsIndex:
446 case CreateJobsIndex:
447 break;
448 case CheckResultsIndex:
449 break;
450 case ReceiveResultsIndex:
451 break;
452 case ReceiveMPQCIndex:
453 if (!vm.count("fragment-path")) {
454 ELOG(1, "'"+ControllerInfo.command+"' require one option: [path to fragment files].");
455 return 255;
456 }
457 break;
458 case RemoveAllIndex:
459 break;
460 case ShutdownIndex:
461 break;
462 case UnknownCommandIndex:
463 default:
464 ELOG(1, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
465 return 255;
466 break;
467 }
468
469 try
470 {
471
472 boost::asio::io_service io_service;
473 FragmentController controller(io_service);
474
475 // Initial phase: information gathering from server
476
477 switch(commandIndex) {
478 case AddJobsIndex:
479 controller.requestIds(ControllerInfo.server, ControllerInfo.serverport, vm["jobfiles"].as< std::vector<std::string> >().size());
480 break;
481 case CreateJobsIndex:
482 controller.requestIds(ControllerInfo.server, ControllerInfo.serverport, 1);
483 break;
484 case CheckResultsIndex:
485 break;
486 case ReceiveResultsIndex:
487 break;
488 case ReceiveMPQCIndex:
489 break;
490 case RemoveAllIndex:
491 break;
492 case ShutdownIndex:
493 break;
494 case UnknownCommandIndex:
495 default:
496 ELOG(0, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
497 return 255;
498 break;
499 }
500
501 {
502 io_service.reset();
503 Info info("io_service: Phase One");
504 io_service.run();
505 }
506
507 // Second phase: Building jobs and sending information to server
508
509 switch(commandIndex) {
510 case AddJobsIndex:
511 {
512 std::vector<FragmentJob::ptr> jobs;
513 const std::string executable(vm["executable"].as< std::string >());
514 const std::vector< std::string > jobfiles = vm["jobfiles"].as< std::vector< std::string > >();
515 for (std::vector< std::string >::const_iterator iter = jobfiles.begin();
516 iter != jobfiles.end(); ++iter) {
517 const JobId_t next_id = controller.getAvailableId();
518 const std::string &filename = *iter;
519 LOG(1, "INFO: Creating MPQCCommandJob with filename'"
520 +filename+"', and id "+toString(next_id)+".");
521 parsejob(jobs, executable, filename, next_id);
522 }
523 controller.addJobs(jobs);
524 controller.sendJobs(ControllerInfo.server, ControllerInfo.serverport);
525 break;
526 }
527 case CreateJobsIndex:
528 {
529 const JobId_t next_id = controller.getAvailableId();
530 std::vector<FragmentJob::ptr> jobs;
531 createjobs(jobs, ControllerInfo.executable, ControllerInfo.jobcommand, next_id);
532 controller.addJobs(jobs);
533 controller.sendJobs(ControllerInfo.server, ControllerInfo.serverport);
534 break;
535 }
536 case CheckResultsIndex:
537 controller.checkResults(ControllerInfo.server, ControllerInfo.serverport);
538 break;
539 case ReceiveResultsIndex:
540 case ReceiveMPQCIndex:
541 controller.receiveResults(ControllerInfo.server, ControllerInfo.serverport);
542 break;
543 case RemoveAllIndex:
544 controller.removeall(ControllerInfo.server, ControllerInfo.serverport);
545 break;
546 case ShutdownIndex:
547 controller.shutdown(ControllerInfo.server, ControllerInfo.serverport);
548 break;
549 case UnknownCommandIndex:
550 default:
551 ELOG(0, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
552 return 255;
553 break;
554 }
555
556 {
557 io_service.reset();
558 Info info("io_service: Phase Two");
559 io_service.run();
560 }
561
562 // Final phase: Print result of command
563
564 switch(commandIndex) {
565 case AddJobsIndex:
566 case CreateJobsIndex:
567 break;
568 case CheckResultsIndex:
569 {
570 const std::pair<size_t, size_t> JobStatus = controller.getJobStatus();
571 LOG(1, "INFO: #" << JobStatus.first << " are waiting in the queue and #" << JobStatus.second << " jobs are calculated so far.");
572 break;
573 }
574 case ReceiveResultsIndex:
575 {
576 std::vector<FragmentResult::ptr> results = controller.getReceivedResults();
577 printReceivedResults(results);
578 break;
579 }
580 case ReceiveMPQCIndex:
581 {
582 const std::string path = vm["fragment-path"].as< std::string >();
583 LOG(1, "INFO: Parsing fragment files from " << path << ".");
584 std::vector<FragmentResult::ptr> results = controller.getReceivedResults();
585 printReceivedMPQCResults(
586 results,
587 path,
588 getNoAtomsFromAdjacencyFile(path));
589 break;
590 }
591 case RemoveAllIndex:
592 break;
593 case ShutdownIndex:
594 break;
595 case UnknownCommandIndex:
596 default:
597 ELOG(0, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
598 return 255;
599 break;
600 }
601 Exitflag = controller.getExitflag();
602 }
603 catch (std::exception& e)
604 {
605 std::cerr << e.what() << std::endl;
606 }
607
608 return Exitflag;
609}
610
Note: See TracBrowser for help on using the repository browser.