source: src/Parser/FormatParserStorage.cpp@ ff4fff9

CombiningParticlePotentialParsing
Last change on this file since ff4fff9 was fac58f, checked in by Frederik Heber <heber@…>, 9 years ago

Converted FormatParser::save() to using vector of const atom ptrs.

  • required to change all save() functions in all parsers.
  • Property mode set to 100644
File size: 12.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/** \file FormatParserStorage.cpp
24 *
25 * date: Jun, 22 2010
26 * author: heber
27 *
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include "CodePatterns/MemDebug.hpp"
36
37#include <iostream>
38#include <fstream>
39
40#include <boost/preprocessor/iteration/local.hpp>
41
42#include "CodePatterns/Assert.hpp"
43#include "CodePatterns/Log.hpp"
44
45#include "molecule.hpp"
46#include "FormatParserStorage.hpp"
47#include "ParserTypes.hpp"
48
49#include "MpqcParser.hpp"
50#include "PcpParser.hpp"
51#include "PdbParser.hpp"
52#include "Psi3Parser.hpp"
53#include "TremoloParser.hpp"
54#include "XmlParser.hpp"
55#include "XyzParser.hpp"
56
57#include "CodePatterns/Singleton_impl.hpp"
58
59const std::string FormatParserStorage::unknownTypeString("unknown");
60
61/** Constructor of class FormatParserStorage.
62 */
63FormatParserStorage::FormatParserStorage()
64{
65 ParserList.resize(ParserTypes_end, NULL);
66 ParserStream.resize(ParserTypes_end, NULL);
67 ParserPresent.resize(ParserTypes_end, false);
68 ParserDesiredOutputFormat.resize(ParserTypes_end, false);
69
70#include "ParserTypes.def"
71
72#define insert_print(z,n,seq,map, before, after) \
73 map .insert( std::make_pair( \
74 BOOST_PP_SEQ_ELEM(n, seq) \
75 , before < \
76 BOOST_PP_SEQ_ELEM(n, seq) \
77 > after \
78 ) );
79
80#define insert_invert_print(z,n,seq,map, before, after) \
81 map .insert( std::make_pair( before < \
82 BOOST_PP_SEQ_ELEM(n, seq) \
83 > after, \
84 BOOST_PP_SEQ_ELEM(n, seq) \
85 ) );
86
87 // fill ParserNames
88#if defined ParserTypes_END // do we have parameters at all?
89#define BOOST_PP_LOCAL_MACRO(n) insert_print(~, n, PARSERSEQUENCE, ParserNames, FormatParserTrait, ::name)
90#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
91#include BOOST_PP_LOCAL_ITERATE()
92#endif
93
94 // fill ParserLookupNames
95#if defined ParserTypes_END // do we have parameters at all?
96#define BOOST_PP_LOCAL_MACRO(n) insert_invert_print(~, n, PARSERSEQUENCE, ParserLookupNames, FormatParserTrait, ::name)
97#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
98#include BOOST_PP_LOCAL_ITERATE()
99#endif
100
101 // fill ParserSuffixes
102#if defined ParserTypes_END // do we have parameters at all?
103#define BOOST_PP_LOCAL_MACRO(n) insert_print(~, n, PARSERSEQUENCE, ParserSuffixes, FormatParserTrait, ::suffix)
104#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
105#include BOOST_PP_LOCAL_ITERATE()
106#endif
107
108 // fill ParserLookupSuffixes
109#if defined ParserTypes_END // do we have parameters at all?
110#define BOOST_PP_LOCAL_MACRO(n) insert_invert_print(~, n, PARSERSEQUENCE, ParserLookupSuffixes, FormatParserTrait, ::suffix)
111#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
112#include BOOST_PP_LOCAL_ITERATE()
113#endif
114
115 // fill ParserAddFunction
116#if defined ParserTypes_END // do we have parameters at all?
117#define BOOST_PP_LOCAL_MACRO(n) insert_print(~, n, PARSERSEQUENCE, ParserAddFunction, &FormatParserStorage::addParser, )
118#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
119#include BOOST_PP_LOCAL_ITERATE()
120#endif
121
122#undef insert_print
123#undef insert_invert_print
124#include "ParserTypes.undef"
125
126 //std::cout << "ParserNames:" << std::endl << ParserNames << std::endl;
127 //std::cout << "ParserSuffixes:" << std::endl << ParserSuffixes << std::endl;
128 //std::cout << "ParserLookupNames:" << std::endl << ParserLookupNames << std::endl;
129 //std::cout << "ParserLookupSuffixes:" << std::endl << ParserLookupSuffixes << std::endl;
130 //std::cout << "ParserAddFunction:" << std::endl << ParserAddFunction << std::endl;
131
132}
133
134/** Destructor of class FormatParserStorage.
135 * Free all stored FormatParsers.
136 * Save on Exit.
137 */
138FormatParserStorage::~FormatParserStorage()
139{
140 for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter)
141 if (ParserPresent[iter]) {
142 // this will also flush the ParserStream
143 delete ParserList[iter];
144 // then we remove the stream itself
145 if (ParserStream[iter] != NULL) {
146 if (ParserStream[iter]->is_open())
147 ParserStream[iter]->close();
148 delete ParserStream[iter];
149 }
150 }
151}
152
153
154/** Tests whether a file and parsers are selected for saving.
155 */
156bool FormatParserStorage::isAbleToSave()
157{
158 if (prefix.empty())
159 return false;
160
161 for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter)
162 if (ParserPresent[iter] && ParserDesiredOutputFormat[iter])
163 return true;
164 return false;
165}
166
167/** Sets the filename of all current parsers in storage to prefix.suffix.
168 * \param &prefix prefix to use.
169 */
170void FormatParserStorage::SetOutputPrefixForAll(std::string &_prefix)
171{
172 prefix=_prefix;
173};
174
175/** Sets \a type as a format to be stored on call of SaveAll.
176 *
177 * @param type type to add to desired output formats
178 */
179void FormatParserStorage::setOutputFormat(ParserTypes type)
180{
181 LOG(0, "STATUS: Adding " << ParserNames[type] << " type to output.");
182 ParserDesiredOutputFormat[type] = true;
183}
184
185/** Sets \a type as a format to be stored on call of SaveAll.
186 *
187 * @param type type to add to desired output formats
188 */
189void FormatParserStorage::setOutputFormat(std::string type)
190{
191 std::map<std::string, ParserTypes>::const_iterator iter = ParserLookupNames.find(type);
192 ASSERT(iter != ParserLookupNames.end(),
193 "FormatParserStorage::setOutputFormat() - output format "+type+" is unknown.");
194 setOutputFormat(iter->second);
195}
196
197/** Saves the world in the desired output formats.
198 *
199 */
200void FormatParserStorage::SaveAll()
201{
202 std::string filename;
203 for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter)
204 if (ParserPresent[iter] && ParserDesiredOutputFormat[iter]) {
205 filename = prefix;
206 filename += ".";
207 filename += ParserSuffixes[iter];
208 ParserStream[iter] = new std::ofstream(filename.c_str());
209 ParserList[iter]->setOstream((std::ostream *)ParserStream[iter]);
210 }
211}
212
213
214ParserTypes FormatParserStorage::getTypeFromName(std::string type)
215{
216 if (ParserLookupNames.find(type) == ParserLookupNames.end()) {
217 ELOG(1, "Unknown type " << type << ".");
218 return ParserTypes_end;
219 } else
220 return ParserLookupNames[type];
221}
222
223ParserTypes FormatParserStorage::getTypeFromSuffix(std::string type)
224{
225 if (ParserLookupSuffixes.find(type) == ParserLookupSuffixes.end()) {
226 ELOG(1, "Unknown type " << type << ".");
227 return ParserTypes_end;
228 } else
229 return ParserLookupSuffixes[type];
230}
231
232const std::string &FormatParserStorage::getNameFromType(ParserTypes type)
233{
234 if (ParserNames.find(type) == ParserNames.end()) {
235 ELOG(1, "Unknown type " << type << ".");
236 return unknownTypeString;
237 } else
238 return ParserNames[type];
239}
240
241const std::string &FormatParserStorage::getSuffixFromType(ParserTypes type)
242{
243 if (ParserSuffixes.find(type) == ParserSuffixes.end()) {
244 ELOG(1, "Unknown type " << type << ".");
245 return unknownTypeString;
246 } else
247 return ParserSuffixes[type];
248}
249
250bool FormatParserStorage::add(ParserTypes ptype)
251{
252 if (ptype != ParserTypes_end) {
253 if (ParserAddFunction.find(ptype) != ParserAddFunction.end()) {
254 (getInstance().*(ParserAddFunction[ptype]))(); // we still need an object to work on ...
255 return true;
256 } else {
257 ELOG(1, "No parser to add for this known type " << ParserNames[ptype] << ", not implemented?");
258 return false;
259 }
260 } else {
261 return false;
262 }
263}
264
265bool FormatParserStorage::add(std::string type)
266{
267 enum ParserTypes Ptype = getTypeFromName(type);
268 return add(Ptype);
269}
270
271/** Recognizes type of file and parse via FormatParserStorage::load().
272 * \param filename path and filename
273 * \return true - parsing ok, false - suffix unknown
274 */
275bool FormatParserStorage::load(boost::filesystem::path filename)
276{
277 return load(filename.string());
278}
279
280/** Recognizes type of file and parse via FormatParserStorage::load().
281 * \param filename path and filename
282 * \return true - parsing ok, false - suffix unknown
283 */
284bool FormatParserStorage::load(std::string &filename)
285{
286 std::string FilenameSuffix = filename.substr(filename.find_last_of('.')+1, filename.length());
287 ifstream input;
288 LOG(0, "STATUS: Loading filler molecule " << filename
289 << " of suffix " << FilenameSuffix << ".");
290 input.open(filename.c_str());
291 const bool status = load(input, FilenameSuffix);
292 input.close();
293
294 return status;
295}
296
297/** Parses an istream depending on its suffix
298 * \param &input input stream
299 * \param suffix
300 * \return true - parsing ok, false - suffix unknown
301 */
302bool FormatParserStorage::load(std::istream &input, std::string &suffix)
303{
304 enum ParserTypes type = getTypeFromSuffix(suffix);
305 if (type != ParserTypes_end)
306 get(type).load(&input);
307 else
308 return false;
309 return true;
310}
311
312/** Stores all selected atoms in an ostream depending on its suffix
313 * \param &output output stream
314 * \param suffix
315 * \return true - storing ok, false - suffix unknown
316 */
317bool FormatParserStorage::saveSelectedAtoms(std::ostream &output, std::string suffix)
318{
319 const std::vector<const atom *> atoms =
320 const_cast<const World &>(World::getInstance()).getSelectedAtoms();
321 return save(output, suffix, atoms);
322}
323
324/** Stores all selected atoms in an ostream depending on its suffix
325 * We store in the order of the atomic ids, not in the order they appear in the molecules.
326 * Hence, we first create a vector from all selected molecules' atoms.
327 *
328 * TODO: Change here atom * to const atom * when FormatParserStorage::save() uses vector<const atom *>
329 *
330 * \param &output output stream
331 * \param suffix
332 * \return true - storing ok, false - suffix unknown
333 */
334bool FormatParserStorage::saveSelectedMolecules(std::ostream &output, std::string suffix)
335{
336 const std::vector<const molecule *> molecules =
337 const_cast<const World &>(World::getInstance()).getSelectedMolecules();
338 std::map<size_t, const atom *> IdAtoms;
339 for (std::vector<const molecule *>::const_iterator MolIter = molecules.begin();
340 MolIter != molecules.end();
341 ++MolIter) {
342 for(molecule::const_iterator AtomIter = (*MolIter)->begin();
343 AtomIter != (*MolIter)->end();
344 ++AtomIter) {
345 IdAtoms.insert( make_pair((*AtomIter)->getId(), (*AtomIter)) );
346 }
347 }
348 std::vector<const atom *> atoms;
349 atoms.reserve(IdAtoms.size());
350 for (std::map<size_t, const atom *>::const_iterator iter = IdAtoms.begin();
351 iter != IdAtoms.end();
352 ++iter) {
353 atoms.push_back(iter->second);
354 }
355 return save(output, suffix, atoms);
356}
357
358/** Stores world in an ostream depending on its suffix
359 * \param &output output stream
360 * \param suffix
361 * \return true - storing ok, false - suffix unknown
362 */
363bool FormatParserStorage::saveWorld(std::ostream &output, std::string suffix)
364{
365 const std::vector<const atom *> atoms =
366 const_cast<const World &>(World::getInstance()).getAllAtoms();
367 return save(output, suffix, atoms);
368}
369
370/** Stores a given vector of \a atoms in an ostream depending on its suffix
371 * \param &output output stream
372 * \param suffix
373 * \return true - storing ok, false - suffix unknown
374 */
375bool FormatParserStorage::save(
376 std::ostream &output,
377 std::string suffix,
378 const std::vector<const atom *> &atoms)
379{
380 enum ParserTypes type = getTypeFromSuffix(suffix);
381 if (type != ParserTypes_end)
382 get(type).save(&output, atoms);
383 else
384 return false;
385 return true;
386}
387
388/** Returns reference to the desired output parser as FormatParser, adds if not present.
389 * \param _type type of desired parser
390 * \return reference to the output FormatParser with desired type
391 */
392FormatParserInterface &FormatParserStorage::get(ParserTypes _type)
393{
394 if (!ParserPresent[_type]) {
395 add(_type);
396 }
397 return *ParserList[_type];
398}
399
400CONSTRUCT_SINGLETON(FormatParserStorage)
Note: See TracBrowser for help on using the repository browser.