/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * Copyright (C) 2013 Frederik Heber. All rights reserved. * Please see the COPYING file or "Copyright notice" in builder.cpp for details. * * * 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 . */ /* * SerializablePotential.cpp * * Created on: 23.11.2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "SerializablePotential.hpp" #include #include #include #include #include #include "CodePatterns/Assert.hpp" #include "CodePatterns/toString.hpp" #include "Potentials/Exceptions.hpp" SerializablePotential::SerializablePotential() : ParticleTypes() {} std::ostream& operator<<(std::ostream &ost, const SerializablePotential &potential) { potential.stream_to(ost); return ost; } void SerializablePotential::stream_to(std::ostream &ost) const { // check stream if (ost.bad()) throw SerializablePotentialException(); /// print parameter key ost << getToken() << ":"; /// print associated particles const SerializablePotential::ParticleTypes_t &types = getParticleTypes(); for (size_t index=0; index < types.size(); ++index) { ost << "\tparticle_type" << index+1 << "=" << types[index]; ost << (index != (types.size()-1) ? std::string(",") : std::string("")); } /// print coefficients const SerializablePotential::ParameterNames_t ¶mNames = getParameterNames(); const SerializablePotential::parameters_t ¶ms = getParameters(); SerializablePotential::ParameterNames_t::const_iterator nameiter = paramNames.begin(); SerializablePotential::parameters_t::const_iterator valueiter = params.begin(); if (!params.empty()) { if (!types.empty()) ost << ","; ost << "\t" << *nameiter << "=" << *valueiter; for (++valueiter, ++nameiter; valueiter != params.end(); ++valueiter, ++nameiter) { ASSERT( nameiter != paramNames.end(), "SerializablePotential::operator<<() - there are less names than parameters."); if (*nameiter != std::string("")) ost << ",\t" << *nameiter << "=" << *valueiter; } } /// print terminating semi-colon ost << ";"; } std::istream& operator>>(std::istream &ist, SerializablePotential &potential) { potential.stream_from(ist); return ist; } void SerializablePotential::stream_from(std::istream &ist) { // check stream if (ist.bad()) throw SerializablePotentialException(); // create copy of current parameters, hence line may contain not all required SerializablePotential::parameters_t params(getParameters()); // read in full line std::string linestring; getline(ist, linestring); const std::string whitespace(" \t"); const size_t strBegin = linestring.find_first_not_of(whitespace); const size_t colonpos = linestring.find(":"); if ((strBegin == std::string::npos) || (colonpos == std::string::npos) || (linestring.substr(strBegin, colonpos-strBegin) != getToken())) throw SerializablePotentialMissingValueException() << SerializablePotentialKey(getName()); // tokenize by "," typedef boost::tokenizer > tokenizer; boost::char_separator pairsep(",\t ;"); std::string remainderstring(linestring.substr(colonpos+1)); tokenizer tokens(remainderstring, pairsep); //skip colon // step through each token ConvertTo ConvertToIndex; ConvertTo ConvertToValue; ConvertTo ConvertToParticleType; for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { const std::string &keyvalue = *tok_iter; const size_t equalitypos = keyvalue.find("="); const std::string key = keyvalue.substr(0,equalitypos); const std::string value = keyvalue.substr(equalitypos+1); /// parse the particle_types const std::string typetoken("particle_type"); const size_t pos = key.find(typetoken); if (pos != std::string::npos) { // split of type and convert rest to index const size_t indexpos = pos+typetoken.length(); const std::string &indexstring = key.substr(indexpos); const size_t index = ConvertToIndex(indexstring); if(index == 0) throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key); // and set the type if (equalitypos == std::string::npos) throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key); setParticleType(index-1, ConvertToParticleType(value)); } else { const size_t index = getParameterIndex(key); // parse the coefficients if (index != (size_t)-1) { if (equalitypos == std::string::npos) throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key); params[index] = ConvertToValue(value); } else { throw SerializablePotentialIllegalKeyException() << SerializablePotentialKey(key); } } } /// set the new paremeters setParameters(params); } const size_t SerializablePotential::getParameterIndex(const std::string &_name) const { const ParameterNames_t& ParameterNames = getParameterNames(); ParameterNames_t::const_iterator iter = std::find(ParameterNames.begin(), ParameterNames.end(), _name); if (iter == ParameterNames.end()) return (size_t)-1; else return std::distance(ParameterNames.begin(), iter); } const std::string SerializablePotential::getName() const { std::string returnstring = getToken() + std::string("_"); BOOST_FOREACH(const ParticleType_t &type, getParticleTypes()) { returnstring += toString(type); } return returnstring; }