Simpatico  v1.10
Processor.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "Processor.h"
9 #include <tools/config/DdMdConfigReader.h>
10 #include <tools/config/DdMdConfigWriter.h>
11 #include <tools/trajectory/LammpsDumpReader.h>
12 #include <util/format/Str.h>
13 
14 // std headers
15 #include <fstream>
16 #include <unistd.h>
17 #include <stdlib.h>
18 
19 namespace Tools
20 {
21 
22  /*
23  * Constructor.
24  */
26  : configReaderPtr_(0),
27  trajectoryReaderPtr_(0),
28  configReaderFactory_(*this),
29  configWriterFactory_(*this),
30  trajectoryReaderFactory_(*this),
31  analyzerManager_(*this)
32  { setClassName("Processor"); }
33 
34  /*
35  * Destructor.
36  */
38  {
39  if (configReaderPtr_) {
40  delete configReaderPtr_;
41  }
42  if (trajectoryReaderPtr_) {
43  delete trajectoryReaderPtr_;
44  }
45  }
46 
47  /*
48  * Process command line options.
49  */
50  void Processor::setOptions(int argc, char * const * argv)
51  {
52 
53  int c;
54  opterr = 0;
55  while ((c = getopt(argc, argv, "ep:c:")) != -1) {
56  switch (c) {
57  case 'e':
59  break;
60  case 'p':
61  fileMaster_.setParamFileName(std::string(optarg));
62  break;
63  case 'c':
64  fileMaster_.setCommandFileName(std::string(optarg));
65  break;
66  case '?':
67  Log::file() << "Unknown option -" << optopt << std::endl;
68  }
69  }
70 
71  }
72 
73  /*
74  * Read default param file.
75  */
77  {
78  if (fileMaster_.paramFileName().empty()) {
79  UTIL_THROW("Empty param file name");
80  }
81  readParam(fileMaster_.paramFile());
82  }
83 
84  /*
85  * Open, read and close a parameter file.
86  */
87  void Processor::readParam(const char* filename)
88  {
89  std::ifstream in;
90  in.open(filename);
91  readParam(in);
92  in.close();
93  }
94 
95  /*
96  * Read parameters from file.
97  */
98  void Processor::readParameters(std::istream& in)
99  {
101  readParamCompositeOptional(in, fileMaster_);
102  readParamComposite(in, analyzerManager_);
103  }
104 
105  /*
106  * Read and execute commands from default command file.
107  */
109  {
110  if (fileMaster_.commandFileName().empty()) {
111  // Read from standard input if no command file name is set
112  readCommands(std::cin);
113  } else {
114  readCommands(fileMaster_.commandFile());
115  }
116  }
117 
118  /*
119  * Read and execute commands from a specified command file.
120  */
121  void Processor::readCommands(std::istream &in)
122  {
123  std::string command;
124  std::string filename;
125  std::ifstream inputFile;
126  std::ofstream outputFile;
127 
128  bool readNext = true;
129  while (readNext) {
130 
131  in >> command;
132  Log::file() << command;
133 
134  if (command == "FINISH") {
135  Log::file() << std::endl;
136  readNext = false;
137  } else
138  if (command == "SET_CONFIG_READER") {
139  std::string classname;
140  in >> classname;
141  Log::file() << " " << classname << std::endl;
142  setConfigReader(classname);
143  } else
144  if (command == "READ_CONFIG") {
145 
146  // If needed, read auxiliary file
147  if (configReader().needsAuxiliaryFile()) {
148  Log::file() << "\nReading auxiliary file: ";
149  in >> filename;
150  Log::file() << filename;
151  fileMaster_.openInputFile(filename, inputFile);
152  configReader().readAuxiliaryFile(inputFile);
153  inputFile.close();
154  }
155 
156  // Read actual configuration file
157  Log::file() << "\nReading config file: ";
158  in >> filename;
159  Log::file() << filename << std::endl;
160  fileMaster_.openInputFile(filename, inputFile);
161  configReader().readConfig(inputFile);
162  inputFile.close();
163 
164  } else
165  if (command == "SET_CONFIG_WRITER") {
166  std::string classname;
167  in >> classname;
168  Log::file() << " " << classname << std::endl;
169  setConfigWriter(classname);
170  } else
171  if (command == "WRITE_CONFIG") {
172  if (configWriter().needsAuxiliaryFile()) {
173  Log::file() << "\nReading auxiliary file: ";
174  in >> filename;
175  Log::file() << filename;
176  fileMaster_.openInputFile(filename, inputFile);
177  configWriter().readAuxiliaryFile(inputFile);
178  inputFile.close();
179  }
180  Log::file() << "\nWriting config file: ";
181  in >> filename;
182  Log::file() << filename << std::endl;
183  fileMaster_.openOutputFile(filename, outputFile);
184  configWriter().writeConfig(outputFile);
185  outputFile.close();
186  } else
187  if (command == "SET_TRAJECTORY_READER") {
188  std::string classname;
189  in >> classname;
190  Log::file() << " " << classname << std::endl;
191  setTrajectoryReader(classname);
192  } else
193  if (command == "ANALYZE_TRAJECTORY") {
194  in >> filename;
195  Log::file() << " " << filename << std::endl;
196  analyzeTrajectory(filename);
197  } else
198  {
199  Log::file() << " Error: Unknown command " << std::endl;
200  readNext = false;
201  }
202 
203  }
204  }
205 
206  // ConfigReader Functions
207 
208  /*
209  * Set ConfigReader style.
210  */
211  void Processor::setConfigReader(const std::string& configStyle)
212  {
213  configReaderPtr_ = configReaderFactory_.factory(configStyle);
214  if (configReaderPtr_ == 0) {
215  std::string msg;
216  msg = "Unrecognized ConfigReader subclass name: ";
217  msg += configStyle;
218  UTIL_THROW(msg.c_str());
219  }
220  // Log::file() << "Setting config reader to class "
221  // << configReaderPtr_->className() << std::endl;
222  }
223 
224  /*
225  * Return the ConfigReader (create default if necessary).
226  */
228  {
229  if (configReaderPtr_ == 0) {
230  configReaderPtr_ = new DdMdConfigReader(*this);
231  assert(configReaderPtr_);
232  }
233  return *configReaderPtr_;
234  }
235 
236  /*
237  * Read a single configuration file.
238  */
239  void Processor::readConfig(std::ifstream& in)
240  {
241  clear();
242  configReader().readConfig(in);
243  }
244 
245  /*
246  * Open, read and close a configuration file.
247  */
248  void Processor::readConfig(const std::string& filename)
249  {
250  std::ifstream file;
251  file.open(filename.c_str());
252  readConfig(file);
253  file.close();
254  }
255 
256  /*
257  * Read and analyze a sequence of configuration files.
258  */
259  void Processor::analyzeConfigs(const std::string& baseFileName,
260  int min, int max, int interval)
261  {
262  // Preconditions
263  if (min < 0) UTIL_THROW("min < 0");
264  if (max < min) UTIL_THROW("max < min");
265  if (interval <= 0) UTIL_THROW("interval <= 0");
266 
267  //Timer timer;
268  std::string filename;
269  std::stringstream indexString;
270  std::ifstream configFile;
271 
272  // Main loop
273  Log::file() << "begin main loop" << std::endl;
274  //timer.start();
275  for (int iStep = min; iStep <= max; iStep += interval) {
276 
277  indexString << iStep;
278  filename = baseFileName;
279  filename += indexString.str();
280  configFile.open(filename.c_str());
281  if (!configFile.is_open()) {
282  std::string msg = "Configuration file is not open. Filename =";
283  msg += filename;
284  UTIL_THROW(msg.c_str());
285  }
286 
287  // Clear the stringstream
288  indexString.str("");
289 
290  clear();
291  readConfig(configFile);
292  configFile.close();
293 
294  #if 0
295  #ifndef SIMP_NOPAIR
296  // Build the configuration CellList
297  pairPotential().buildCellList();
298  #endif
299 
300  #ifdef UTIL_DEBUG
301  isValid();
302  #endif
303  #endif
304 
305  // Initialize analyzers (taking in molecular information).
306  if (iStep == min) {
307  analyzerManager_.setup();
308  }
309 
310  // Sample property values
311  analyzerManager_.sample(iStep);
312 
313  }
314  //timer.stop();
315  Log::file() << "end main loop" << std::endl;
316 
317  // Output results of all analyzers to output files
318  analyzerManager_.output();
319 
320  }
321 
322  // ConfigWriter Functions
323 
324  /*
325  * Set ConfigWriter style.
326  */
327  void Processor::setConfigWriter(const std::string& configStyle)
328  {
329  configWriterPtr_ = configWriterFactory_.factory(configStyle);
330  if (configWriterPtr_ == 0) {
331  std::string msg;
332  msg = "Unrecognized ConfigWriter subclass name: ";
333  msg += configStyle;
334  UTIL_THROW(msg.c_str());
335  }
336  }
337 
338  /*
339  * Return the ConfigWriter (create default if necessary).
340  */
342  {
343  if (configWriterPtr_ == 0) {
344  configWriterPtr_ = new DdMdConfigWriter(*this);
345  assert(configWriterPtr_);
346  }
347  return *configWriterPtr_;
348  }
349 
350  /*
351  * Read a configuration file.
352  */
353  void Processor::writeConfig(std::ofstream& in)
354  { configWriter().writeConfig(in); }
355 
356  /*
357  * Open, write and close a configuration file.
358  */
359  void Processor::writeConfig(const std::string& filename)
360  {
361  std::ofstream file;
362  file.open(filename.c_str());
363  writeConfig(file);
364  file.close();
365  }
366 
367  // Trajectory Analysis
368 
369  /*
370  * Set TrajectoryReader style.
371  */
372  void Processor::setTrajectoryReader(const std::string& trajectoryStyle)
373  {
374  trajectoryReaderPtr_ =
375  trajectoryReaderFactory_.factory(trajectoryStyle);
376  if (trajectoryReaderPtr_ == 0) {
377  std::string msg;
378  msg = "Unrecognized TrajectoryReader subclass name: ";
379  msg += trajectoryStyle;
380  UTIL_THROW(msg.c_str());
381  }
382  }
383 
384  /*
385  * Return the TrajectoryReader (create default if necessary).
386  */
388  {
389  if (trajectoryReaderPtr_ == 0) {
390  trajectoryReaderPtr_ = new LammpsDumpReader(*this);
391  assert(trajectoryReaderPtr_);
392  }
393  return *trajectoryReaderPtr_;
394  }
395 
396  /*
397  * Read and analyze a trajectory file.
398  */
399  void Processor::analyzeTrajectory(const std::string& filename)
400  {
401 
402  // Open file
403  std::ifstream file;
404  if (trajectoryReader().isBinary()) {
405  fileMaster_.openInputFile(filename, file,
406  std::ios::in | std::ios::binary);
407  } else {
408  fileMaster_.openInputFile(filename, file);
409  }
410  if (!file.is_open()) {
411  std::string msg = "Trajectory file is not open. Filename =";
412  msg += filename;
413  UTIL_THROW(msg.c_str());
414  }
415 
416  // Initialize analyzers (taking in molecular information).
417  analyzerManager_.setup();
418 
419  // Main loop
421  Log::file() << "begin main loop" << std::endl;
422  int iStep = 0;
423  bool notEnd = true;
424  while (notEnd) {
425  notEnd = trajectoryReader().readFrame(file);
426  if (notEnd) {
427  analyzerManager_.sample(iStep);
428  ++iStep;
429  }
430  }
431  Log::file() << "end main loop" << std::endl;
432 
433  // Output any final results of analyzers to output files
434  analyzerManager_.output();
435 
436  file.close();
437  }
438 
439  /*
440  * Return FileMaster.
441  */
443  { return fileMaster_; }
444 
445 }
std::istream & commandFile()
Get the command input stream by reference.
Definition: FileMaster.cpp:178
void readConfig(std::ifstream &in)
Read a single configuration file.
Definition: Processor.cpp:239
void setCommandFileName(const std::string &commandFileName)
Set the command file name.
Definition: FileMaster.cpp:112
Abstract reader/writer for configuration files.
Definition: ConfigReader.h:27
std::string paramFileName() const
Return the param file name, if any.
Definition: FileMaster.h:466
ConfigReader * factory(const std::string &subclassName) const
Create an instance of a specified subclass of ConfigReader.
Abstract trajectory file reader.
void openOutputFile(const std::string &filename, std::ofstream &out, std::ios_base::openmode mode=std::ios_base::out) const
Open an output file.
Definition: FileMaster.cpp:290
virtual void readAuxiliaryFile(std::ifstream &file)
Read auxiliary file.
Definition: ConfigReader.h:69
static void setEcho(bool echo=true)
Enable or disable echoing for all subclasses of ParamComponent.
Native / default DdMd format for configuration files.
virtual void writeConfig(std::ofstream &file)=0
Write configuration file.
void openInputFile(const std::string &filename, std::ifstream &in, std::ios_base::openmode mode=std::ios_base::in) const
Open an input file.
Definition: FileMaster.cpp:273
ConfigWriter & configWriter()
Return the current ConfigWriter (create default if necessary).
Definition: Processor.cpp:341
void readParam()
Read parameter file specified in command line.
Definition: Processor.cpp:76
ConfigReader & configReader()
Return the current ConfigReader (create default if necessary).
Definition: Processor.cpp:227
~Processor()
Destructor.
Definition: Processor.cpp:37
Abstract reader/writer for configuration files.
std::istream & paramFile()
Get a default parameter stream by reference.
Definition: FileMaster.cpp:155
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
virtual void readHeader(std::ifstream &file)
Read a header (if any).
void writeConfig(std::ofstream &in)
Write a single configuration file.
Definition: Processor.cpp:353
void setup()
Call setup method of each Analyzer.
void setConfigWriter(const std::string &configWriterName)
Set ConfigWriter style (creates a ConfigWriter).
Definition: Processor.cpp:327
virtual void readConfig(std::ifstream &file)=0
Read a configuration file.
void sample(long iStep)
Call sample method of each Analyzer, if scheduled.
FileMaster & fileMaster()
Return FileMaster if active, or throw Exception.
Definition: Processor.cpp:442
Single-processor classes for pre- and post-processing MD trajectories.
void output()
Call output method of each analyzer.
std::string commandFileName() const
Return the command file name.
Definition: FileMaster.h:472
void setOptions(int argc, char *const *argv)
Process command line options.
Definition: Processor.cpp:50
void analyzeConfigs(const std::string &baseFileName, int min, int max, int interval=1)
Read and analyze a sequence of numbered configuration files.
Definition: Processor.cpp:259
void readParamCompositeOptional(std::istream &in, ParamComposite &child, bool next=true)
Add and attempt to read an optional child ParamComposite.
static std::ostream & file()
Get log ostream by reference.
Definition: Log.cpp:57
A FileMaster manages input and output files for a simulation.
Definition: FileMaster.h:142
Native / default DdMd format for configuration files.
ConfigWriter * factory(const std::string &subclassName) const
Create an instance of a specified subclass of ConfigWriter.
TrajectoryReader & trajectoryReader()
Return the current TrajectoryReader (create default if necessary).
Definition: Processor.cpp:387
virtual bool readFrame(std::ifstream &file)=0
Read a frame.
void clear()
Clear all atoms and groups.
Reader for lammps dump trajectory file format.
void analyzeTrajectory(const std::string &filename)
Open, read, analyze and close a single trajectory file.
Definition: Processor.cpp:399
void setClassName(const char *className)
Set class name string.
void setParamFileName(const std::string &paramFileName)
Set the parameter file name.
Definition: FileMaster.cpp:106
void readParamComposite(std::istream &in, ParamComposite &child, bool next=true)
Add and read a required child ParamComposite.
virtual void readAuxiliaryFile(std::ifstream &file)
Read auxiliary file (empty default implementation).
TrajectoryReader * factory(const std::string &subclassName) const
Create an instance of a specified subclass of TrajectoryReader.
void setConfigReader(const std::string &configReaderName)
Set ConfigReader style (creates a ConfigReader).
Definition: Processor.cpp:211
void readParameters(std::istream &in)
Read parameters.
Definition: Processor.cpp:98
void readParameters(std::istream &in)
Read parameters.
Processor()
Constructor.
Definition: Processor.cpp:25
void setTrajectoryReader(const std::string &trajectoryStyle)
Set TrajectoryReader style (creates a TrajectoryReader).
Definition: Processor.cpp:372
void readCommands()
Read command file specified in command line.
Definition: Processor.cpp:108