source: src/Fragmentation/Automation/controller.cpp@ 3add4f

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 3add4f was 4dd16e, checked in by Frederik Heber <heber@…>, 13 years ago

Placed some commodity functions from controller.cpp into FragmentController.

  • Property mode set to 100644
File size: 9.9 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 <fstream>
32#include <iostream>
33#include <map>
34#include <sstream>
35#include <streambuf>
36#include <vector>
37
38#include "atexit.hpp"
39#include "CodePatterns/Info.hpp"
40#include "CodePatterns/Log.hpp"
41#include "FragmentController.hpp"
42#include "Jobs/MPQCCommandJob.hpp"
43#include "Jobs/SystemCommandJob.hpp"
44#include "Results/FragmentResult.hpp"
45
46enum CommandIndices {
47 UnknownCommandIndex = 0,
48 AddJobsIndex = 1,
49 CreateJobsIndex = 2,
50 CheckResultsIndex = 3,
51 ReceiveResultsIndex = 4,
52 ReceiveMPQCIndex = 5,
53 ShutdownIndex = 6,
54};
55
56
57/** Creates a SystemCommandJob out of give \a command with \a argument.
58 *
59 * @param jobs created job is added to this vector
60 * @param command command to execute for SystemCommandJob
61 * @param argument argument for command to execute
62 * @param nextid id for this job
63 */
64void createjobs(
65 std::vector<FragmentJob::ptr> &jobs,
66 const std::string &command,
67 const std::string &argument,
68 const JobId_t nextid)
69{
70
71 FragmentJob::ptr testJob( new SystemCommandJob(command, argument, nextid) );
72 jobs.push_back(testJob);
73 LOG(1, "INFO: Added one SystemCommandJob.");
74}
75
76/** Creates a MPQCCommandJob with argument \a filename.
77 *
78 * @param jobs created job is added to this vector
79 * @param filename filename being argument to job
80 * @param nextid id for this job
81 */
82void parsejob(
83 std::vector<FragmentJob::ptr> &jobs,
84 const std::string &filename,
85 const JobId_t nextid)
86{
87 std::ifstream file;
88 file.open(filename.c_str());
89 ASSERT( file.good(), "parsejob() - file "+filename+" does not exist.");
90 std::string output((std::istreambuf_iterator<char>(file)),
91 std::istreambuf_iterator<char>());
92 FragmentJob::ptr testJob( new MPQCCommandJob(output, nextid) );
93 jobs.push_back(testJob);
94 file.close();
95 LOG(1, "INFO: Added MPQCCommandJob from file "+filename+".");
96}
97
98/** Print received results.
99 *
100 * @param results received results to print
101 */
102void printReceivedResults(std::vector<FragmentResult::ptr> &results)
103{
104 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
105 iter != results.end(); ++iter)
106 LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
107}
108
109/** Print received results.
110 *
111 * @param results vector of all received FragmentResult's
112 * @param KeySetFilename filename containing keysets
113 */
114void printreceivedmpqcresults(std::vector<FragmentResult::ptr> &results, const std::string &KeySetFilename)
115{
116 // parse in KeySetfile
117// const size_t MAXBUFFER = 256;
118 std::ifstream inputfile;
119 inputfile.open(KeySetFilename.c_str());
120// while (inputfile.getline(buffer, MAXBUFFER)) {
121//
122// }
123 inputfile.close();
124
125 // combine all found data
126 std::vector<MPQCData> fragmentData(results.size());
127 MPQCData combinedData;
128
129 LOG(2, "DEBUG: Parsing now through " << results.size() << " results.");
130 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
131 iter != results.end(); ++iter) {
132 LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
133 MPQCData extractedData;
134 std::stringstream inputstream((*iter)->result);
135 boost::archive::text_iarchive ia(inputstream);
136 ia >> extractedData;
137 LOG(1, "INFO: extracted data is " << extractedData << ".");
138 }
139}
140
141/** Returns a unique index for every command to allow switching over it.
142 *
143 * \param &commandmap map with command strings
144 * \param &cmd command string
145 * \return index from CommandIndices: UnkownCommandIndex - unknown command, else - command index
146 */
147CommandIndices getCommandIndex(std::map<std::string, CommandIndices> &commandmap, const std::string &cmd)
148{
149 std::map<std::string, CommandIndices>::const_iterator iter = commandmap.find(cmd);
150 if (iter != commandmap.end())
151 return iter->second;
152 else
153 return UnknownCommandIndex;
154}
155
156
157int main(int argc, char* argv[])
158{
159 // from this moment on, we need to be sure to deeinitialize in the correct order
160 // this is handled by the cleanup function
161 atexit(cleanUp);
162
163 setVerbosity(3);
164
165 size_t Exitflag = 0;
166 typedef std::map<std::string, CommandIndices> CommandsMap_t;
167 CommandsMap_t CommandsMap;
168 CommandsMap.insert( std::make_pair("addjobs", AddJobsIndex) );
169 CommandsMap.insert( std::make_pair("createjobs", CreateJobsIndex) );
170 CommandsMap.insert( std::make_pair("checkresults", CheckResultsIndex) );
171 CommandsMap.insert( std::make_pair("receiveresults", ReceiveResultsIndex) );
172 CommandsMap.insert( std::make_pair("receivempqc", ReceiveMPQCIndex) );
173 CommandsMap.insert( std::make_pair("shutdown", ShutdownIndex) );
174 try
175 {
176 // Check command line arguments.
177 if (argc < 4)
178 {
179 std::cerr << "Usage: " << argv[0] << " <host> <port> <command> [options to command]" << std::endl;
180 std::cerr << "List of available commands:" << std::endl;
181 for(CommandsMap_t::const_iterator iter = CommandsMap.begin();
182 iter != CommandsMap.end(); ++iter) {
183 std::cerr << "\t" << iter->first << std::endl;
184 }
185 return 1;
186 }
187
188 boost::asio::io_service io_service;
189 FragmentController controller(io_service);
190
191 // Initial phase: information gathering from server
192
193 switch(getCommandIndex(CommandsMap, argv[3])) {
194 case AddJobsIndex:
195 {
196 if (argc < 5) {
197 ELOG(1, "Please add a filename for the MPQCCommandJob.");
198 } else {
199 // get an id for every filename
200 for (int argcount = 4; argcount < argc; ++argcount) {
201 controller.requestId(argv[1], argv[2]);
202 }
203 }
204 break;
205 }
206 case CreateJobsIndex:
207 {
208 std::vector<FragmentJob::ptr> jobs;
209 if (argc < 6) {
210 ELOG(1, "'createjobs' requires two options: [command] [argument].");
211 } else {
212 controller.requestId(argv[1], argv[2]);
213 }
214 break;
215 }
216 case CheckResultsIndex:
217 break;
218 case ReceiveResultsIndex:
219 break;
220 case ReceiveMPQCIndex:
221 break;
222 case ShutdownIndex:
223 break;
224 case UnknownCommandIndex:
225 default:
226 ELOG(1, "Unrecognized command '"+toString(argv[3])+"'.");
227 break;
228 }
229
230 {
231 io_service.reset();
232 Info info("io_service: Phase One");
233 io_service.run();
234 }
235
236 // Second phase: Building jobs and sending information to server
237
238 switch(getCommandIndex(CommandsMap, argv[3])) {
239 case AddJobsIndex:
240 {
241 std::vector<FragmentJob::ptr> jobs;
242 if (argc < 5) {
243 ELOG(1, "Please add a filename for the MPQCCommandJob.");
244 } else {
245 for (int argcount = 4; argcount < argc; ++argcount) {
246 const JobId_t next_id = controller.getAvailableId();
247 const std::string filename(argv[argcount]);
248 LOG(1, "INFO: Creating MPQCCommandJob with filename'"
249 +filename+"', and id "+toString(next_id)+".");
250 parsejob(jobs, filename, next_id);
251 }
252 controller.addJobs(jobs);
253 controller.sendJobs(argv[1], argv[2]);
254 }
255 break;
256 }
257 case CreateJobsIndex:
258 {
259 std::vector<FragmentJob::ptr> jobs;
260 if (argc < 6) {
261 ELOG(1, "'createjobs' requires two options: [command] [argument].");
262 } else {
263 const JobId_t next_id = controller.getAvailableId();
264 createjobs(jobs, argv[4], argv[5], next_id);
265 controller.addJobs(jobs);
266 controller.sendJobs(argv[1], argv[2]);
267 }
268 break;
269 }
270 case CheckResultsIndex:
271 {
272 controller.checkResults(argv[1], argv[2]);
273 break;
274 }
275 case ReceiveResultsIndex:
276 {
277 controller.receiveResults(argv[1], argv[2]);
278 break;
279 }
280 case ReceiveMPQCIndex:
281 {
282 controller.receiveResults(argv[1], argv[2]);
283 break;
284 }
285 case ShutdownIndex:
286 {
287 controller.shutdown(argv[1], argv[2]);
288 break;
289 }
290 case UnknownCommandIndex:
291 default:
292 ELOG(0, "Unrecognized command '"+toString(argv[3])+"'.");
293 break;
294 }
295
296 {
297 io_service.reset();
298 Info info("io_service: Phase Two");
299 io_service.run();
300 }
301
302 // Final phase: Print result of command
303
304 switch(getCommandIndex(CommandsMap, argv[3])) {
305 case AddJobsIndex:
306 case CreateJobsIndex:
307 break;
308 case CheckResultsIndex:
309 {
310 controller.printDoneJobs();
311 break;
312 }
313 case ReceiveResultsIndex:
314 {
315 std::vector<FragmentResult::ptr> results = controller.getReceivedResults();
316 printReceivedResults(results);
317 break;
318 }
319 case ReceiveMPQCIndex:
320 {
321 if (argc == 4) {
322 ELOG(1, "'receivempqc' requires one option: [KeySetFilename].");
323 } else {
324 const std::string KeySetFilename = argv[4];
325 LOG(1, "INFO: Parsing id associations from " << KeySetFilename << ".");
326 std::vector<FragmentResult::ptr> results = controller.getReceivedResults();
327 printreceivedmpqcresults(results, KeySetFilename);
328 }
329 break;
330 }
331 case ShutdownIndex:
332 break;
333 case UnknownCommandIndex:
334 default:
335 ELOG(0, "Unrecognized command '"+toString(argv[3])+"'.");
336 break;
337 }
338 Exitflag = controller.getExitflag();
339 }
340 catch (std::exception& e)
341 {
342 std::cerr << e.what() << std::endl;
343 }
344
345 return Exitflag;
346}
347
Note: See TracBrowser for help on using the repository browser.