/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/** \file FormatParserStorage.cpp
*
* date: Jun, 22 2010
* author: heber
*
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include "CodePatterns/MemDebug.hpp"
#include
#include
#include
#include "CodePatterns/Assert.hpp"
#include "CodePatterns/Log.hpp"
#include "molecule.hpp"
#include "FormatParserStorage.hpp"
#include "ParserTypes.hpp"
#include "MpqcParser.hpp"
#include "PcpParser.hpp"
#include "PdbParser.hpp"
#include "Psi3Parser.hpp"
#include "TremoloParser.hpp"
#include "XmlParser.hpp"
#include "XyzParser.hpp"
#include "CodePatterns/Singleton_impl.hpp"
const std::string FormatParserStorage::unknownTypeString("unknown");
/** Constructor of class FormatParserStorage.
*/
FormatParserStorage::FormatParserStorage()
{
ParserList.resize(ParserTypes_end, NULL);
ParserStream.resize(ParserTypes_end, NULL);
ParserPresent.resize(ParserTypes_end, false);
ParserDesiredOutputFormat.resize(ParserTypes_end, false);
#include "ParserTypes.def"
#define insert_print(z,n,seq,map, before, after) \
map .insert( std::make_pair( \
BOOST_PP_SEQ_ELEM(n, seq) \
, before < \
BOOST_PP_SEQ_ELEM(n, seq) \
> after \
) );
#define insert_invert_print(z,n,seq,map, before, after) \
map .insert( std::make_pair( before < \
BOOST_PP_SEQ_ELEM(n, seq) \
> after, \
BOOST_PP_SEQ_ELEM(n, seq) \
) );
// fill ParserNames
#if defined ParserTypes_END // do we have parameters at all?
#define BOOST_PP_LOCAL_MACRO(n) insert_print(~, n, PARSERSEQUENCE, ParserNames, FormatParserTrait, ::name)
#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
#include BOOST_PP_LOCAL_ITERATE()
#endif
// fill ParserLookupNames
#if defined ParserTypes_END // do we have parameters at all?
#define BOOST_PP_LOCAL_MACRO(n) insert_invert_print(~, n, PARSERSEQUENCE, ParserLookupNames, FormatParserTrait, ::name)
#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
#include BOOST_PP_LOCAL_ITERATE()
#endif
// fill ParserSuffixes
#if defined ParserTypes_END // do we have parameters at all?
#define BOOST_PP_LOCAL_MACRO(n) insert_print(~, n, PARSERSEQUENCE, ParserSuffixes, FormatParserTrait, ::suffix)
#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
#include BOOST_PP_LOCAL_ITERATE()
#endif
// fill ParserLookupSuffixes
#if defined ParserTypes_END // do we have parameters at all?
#define BOOST_PP_LOCAL_MACRO(n) insert_invert_print(~, n, PARSERSEQUENCE, ParserLookupSuffixes, FormatParserTrait, ::suffix)
#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
#include BOOST_PP_LOCAL_ITERATE()
#endif
// fill ParserAddFunction
#if defined ParserTypes_END // do we have parameters at all?
#define BOOST_PP_LOCAL_MACRO(n) insert_print(~, n, PARSERSEQUENCE, ParserAddFunction, &FormatParserStorage::addParser, )
#define BOOST_PP_LOCAL_LIMITS (0, ParserTypes_END-1)
#include BOOST_PP_LOCAL_ITERATE()
#endif
#undef insert_print
#undef insert_invert_print
#include "ParserTypes.undef"
//std::cout << "ParserNames:" << std::endl << ParserNames << std::endl;
//std::cout << "ParserSuffixes:" << std::endl << ParserSuffixes << std::endl;
//std::cout << "ParserLookupNames:" << std::endl << ParserLookupNames << std::endl;
//std::cout << "ParserLookupSuffixes:" << std::endl << ParserLookupSuffixes << std::endl;
//std::cout << "ParserAddFunction:" << std::endl << ParserAddFunction << std::endl;
}
/** Destructor of class FormatParserStorage.
* Free all stored FormatParsers.
* Save on Exit.
*/
FormatParserStorage::~FormatParserStorage()
{
for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter)
if (ParserPresent[iter]) {
// this will also flush the ParserStream
delete ParserList[iter];
// then we remove the stream itself
if (ParserStream[iter] != NULL) {
if (ParserStream[iter]->is_open())
ParserStream[iter]->close();
delete ParserStream[iter];
}
}
}
/** Tests whether a file and parsers are selected for saving.
*/
bool FormatParserStorage::isAbleToSave()
{
if (prefix.empty())
return false;
for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter)
if (ParserPresent[iter] && ParserDesiredOutputFormat[iter])
return true;
return false;
}
/** Sets the filename of all current parsers in storage to prefix.suffix.
* \param &prefix prefix to use.
*/
void FormatParserStorage::SetOutputPrefixForAll(std::string &_prefix)
{
prefix=_prefix;
};
/** Sets \a type as a format to be stored on call of SaveAll.
*
* @param type type to add to desired output formats
*/
void FormatParserStorage::setOutputFormat(ParserTypes type)
{
LOG(0, "STATUS: Adding " << ParserNames[type] << " type to output.");
ParserDesiredOutputFormat[type] = true;
}
/** Sets \a type as a format to be stored on call of SaveAll.
*
* @param type type to add to desired output formats
*/
void FormatParserStorage::setOutputFormat(std::string type)
{
std::map::const_iterator iter = ParserLookupNames.find(type);
ASSERT(iter != ParserLookupNames.end(),
"FormatParserStorage::setOutputFormat() - output format "+type+" is unknown.");
setOutputFormat(iter->second);
}
/** Saves the world in the desired output formats.
*
*/
void FormatParserStorage::SaveAll()
{
std::string filename;
for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter)
if (ParserPresent[iter] && ParserDesiredOutputFormat[iter]) {
filename = prefix;
filename += ".";
filename += ParserSuffixes[iter];
ParserStream[iter] = new std::ofstream(filename.c_str());
ParserList[iter]->setOstream((std::ostream *)ParserStream[iter]);
}
}
ParserTypes FormatParserStorage::getTypeFromName(std::string type)
{
if (ParserLookupNames.find(type) == ParserLookupNames.end()) {
ELOG(1, "Unknown type " << type << ".");
return ParserTypes_end;
} else
return ParserLookupNames[type];
}
ParserTypes FormatParserStorage::getTypeFromSuffix(std::string type)
{
if (ParserLookupSuffixes.find(type) == ParserLookupSuffixes.end()) {
ELOG(1, "Unknown type " << type << ".");
return ParserTypes_end;
} else
return ParserLookupSuffixes[type];
}
const std::string &FormatParserStorage::getNameFromType(ParserTypes type)
{
if (ParserNames.find(type) == ParserNames.end()) {
ELOG(1, "Unknown type " << type << ".");
return unknownTypeString;
} else
return ParserNames[type];
}
const std::string &FormatParserStorage::getSuffixFromType(ParserTypes type)
{
if (ParserSuffixes.find(type) == ParserSuffixes.end()) {
ELOG(1, "Unknown type " << type << ".");
return unknownTypeString;
} else
return ParserSuffixes[type];
}
bool FormatParserStorage::add(ParserTypes ptype)
{
if (ptype != ParserTypes_end) {
if (ParserAddFunction.find(ptype) != ParserAddFunction.end()) {
(getInstance().*(ParserAddFunction[ptype]))(); // we still need an object to work on ...
return true;
} else {
ELOG(1, "No parser to add for this known type " << ParserNames[ptype] << ", not implemented?");
return false;
}
} else {
return false;
}
}
bool FormatParserStorage::add(std::string type)
{
enum ParserTypes Ptype = getTypeFromName(type);
return add(Ptype);
}
/** Recognizes type of file and parse via FormatParserStorage::load().
* \param filename path and filename
* \return true - parsing ok, false - suffix unknown
*/
bool FormatParserStorage::load(boost::filesystem::path filename)
{
return load(filename.string());
}
/** Recognizes type of file and parse via FormatParserStorage::load().
* \param filename path and filename
* \return true - parsing ok, false - suffix unknown
*/
bool FormatParserStorage::load(std::string &filename)
{
std::string FilenameSuffix = filename.substr(filename.find_last_of('.')+1, filename.length());
ifstream input;
LOG(0, "STATUS: Loading filler molecule " << filename
<< " of suffix " << FilenameSuffix << ".");
input.open(filename.c_str());
const bool status = load(input, FilenameSuffix);
input.close();
return status;
}
/** Parses an istream depending on its suffix
* \param &input input stream
* \param suffix
* \return true - parsing ok, false - suffix unknown
*/
bool FormatParserStorage::load(std::istream &input, std::string &suffix)
{
enum ParserTypes type = getTypeFromSuffix(suffix);
if (type != ParserTypes_end)
get(type).load(&input);
else
return false;
return true;
}
/** Stores all selected atoms in an ostream depending on its suffix
* \param &output output stream
* \param suffix
* \return true - storing ok, false - suffix unknown
*/
bool FormatParserStorage::saveSelectedAtoms(std::ostream &output, std::string suffix)
{
const std::vector atoms =
const_cast(World::getInstance()).getSelectedAtoms();
return save(output, suffix, atoms);
}
/** Stores all selected atoms in an ostream depending on its suffix
* We store in the order of the atomic ids, not in the order they appear in the molecules.
* Hence, we first create a vector from all selected molecules' atoms.
*
* TODO: Change here atom * to const atom * when FormatParserStorage::save() uses vector
*
* \param &output output stream
* \param suffix
* \return true - storing ok, false - suffix unknown
*/
bool FormatParserStorage::saveSelectedMolecules(std::ostream &output, std::string suffix)
{
const std::vector molecules =
const_cast(World::getInstance()).getSelectedMolecules();
std::map IdAtoms;
for (std::vector::const_iterator MolIter = molecules.begin();
MolIter != molecules.end();
++MolIter) {
for(molecule::const_iterator AtomIter = (*MolIter)->begin();
AtomIter != (*MolIter)->end();
++AtomIter) {
IdAtoms.insert( make_pair((*AtomIter)->getId(), (*AtomIter)) );
}
}
std::vector atoms;
atoms.reserve(IdAtoms.size());
for (std::map::const_iterator iter = IdAtoms.begin();
iter != IdAtoms.end();
++iter) {
atoms.push_back(iter->second);
}
return save(output, suffix, atoms);
}
/** Stores world in an ostream depending on its suffix
* \param &output output stream
* \param suffix
* \return true - storing ok, false - suffix unknown
*/
bool FormatParserStorage::saveWorld(std::ostream &output, std::string suffix)
{
const std::vector atoms =
const_cast(World::getInstance()).getAllAtoms();
return save(output, suffix, atoms);
}
/** Stores a given vector of \a atoms in an ostream depending on its suffix
* \param &output output stream
* \param suffix
* \return true - storing ok, false - suffix unknown
*/
bool FormatParserStorage::save(
std::ostream &output,
std::string suffix,
const std::vector &atoms)
{
enum ParserTypes type = getTypeFromSuffix(suffix);
if (type != ParserTypes_end)
get(type).save(&output, atoms);
else
return false;
return true;
}
/** Returns reference to the desired output parser as FormatParser, adds if not present.
* \param _type type of desired parser
* \return reference to the output FormatParser with desired type
*/
FormatParserInterface &FormatParserStorage::get(ParserTypes _type)
{
if (!ParserPresent[_type]) {
add(_type);
}
return *ParserList[_type];
}
CONSTRUCT_SINGLETON(FormatParserStorage)