/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /** \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 "TremoloParser.hpp" #include "XyzParser.hpp" #include "CodePatterns/Singleton_impl.hpp" /** Constructor of class FormatParserStorage. */ FormatParserStorage::FormatParserStorage() { ParserList.resize(ParserTypes_end, NULL); ParserStream.resize(ParserTypes_end, NULL); ParserPresent.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]) { if (ParserStream[iter]->is_open()) ParserStream[iter]->close(); delete ParserStream[iter]; delete ParserList[iter]; } } /** 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; }; void FormatParserStorage::SaveAll() { std::string filename; for (ParserTypes iter = ParserTypes_begin; iter < ParserTypes_end; ++iter) if (ParserPresent[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()) { DoeLog(1) && (eLog() << Verbose(1) << "Unknown type " << type << "." << endl); return ParserTypes_end; } else return ParserLookupNames[type]; } ParserTypes FormatParserStorage::getTypeFromSuffix(std::string type) { if (ParserLookupSuffixes.find(type) == ParserLookupSuffixes.end()) { DoeLog(1) && (eLog() << Verbose(1) << "Unknown type " << type << "." << endl); return ParserTypes_end; } else return ParserLookupSuffixes[type]; } bool FormatParserStorage::add(ParserTypes ptype) { if (ptype != ParserTypes_end) { if (ParserAddFunction.find(ptype) != ParserAddFunction.end()) { LOG(0, "STATUS: Adding " << ParserNames[ptype] << " type to output."); (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); } /** 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) { std::vector atoms = 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. * \param &output output stream * \param suffix * \return true - storing ok, false - suffix unknown */ bool FormatParserStorage::saveSelectedMolecules(std::ostream &output, std::string suffix) { std::vector molecules = World::getInstance().getSelectedMolecules(); std::map IdAtoms; for (std::vector::const_iterator MolIter = molecules.begin(); MolIter != molecules.end(); ++MolIter) { for(molecule::atomSet::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) { std::vector atoms = 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)