| 1 | /*
 | 
|---|
| 2 |  * Project: MoleCuilder
 | 
|---|
| 3 |  * Description: creates and alters molecular systems
 | 
|---|
| 4 |  * Copyright (C)  2012 University of Bonn. All rights reserved.
 | 
|---|
| 5 |  * Copyright (C)  2013 Frederik Heber. All rights reserved.
 | 
|---|
| 6 |  * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
 | 
|---|
| 7 |  * 
 | 
|---|
| 8 |  *
 | 
|---|
| 9 |  *   This file is part of MoleCuilder.
 | 
|---|
| 10 |  *
 | 
|---|
| 11 |  *    MoleCuilder is free software: you can redistribute it and/or modify
 | 
|---|
| 12 |  *    it under the terms of the GNU General Public License as published by
 | 
|---|
| 13 |  *    the Free Software Foundation, either version 2 of the License, or
 | 
|---|
| 14 |  *    (at your option) any later version.
 | 
|---|
| 15 |  *
 | 
|---|
| 16 |  *    MoleCuilder is distributed in the hope that it will be useful,
 | 
|---|
| 17 |  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 18 |  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 19 |  *    GNU General Public License for more details.
 | 
|---|
| 20 |  *
 | 
|---|
| 21 |  *    You should have received a copy of the GNU General Public License
 | 
|---|
| 22 |  *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>. 
 | 
|---|
| 23 |  */
 | 
|---|
| 24 | 
 | 
|---|
| 25 | /*
 | 
|---|
| 26 |  * SerializablePotential.cpp
 | 
|---|
| 27 |  *
 | 
|---|
| 28 |  *  Created on: 23.11.2012
 | 
|---|
| 29 |  *      Author: heber
 | 
|---|
| 30 |  */
 | 
|---|
| 31 | 
 | 
|---|
| 32 | // include config.h
 | 
|---|
| 33 | #ifdef HAVE_CONFIG_H
 | 
|---|
| 34 | #include <config.h>
 | 
|---|
| 35 | #endif
 | 
|---|
| 36 | 
 | 
|---|
| 37 | #include "CodePatterns/MemDebug.hpp"
 | 
|---|
| 38 | 
 | 
|---|
| 39 | #include "SerializablePotential.hpp"
 | 
|---|
| 40 | 
 | 
|---|
| 41 | #include <algorithm>
 | 
|---|
| 42 | #include <boost/foreach.hpp>
 | 
|---|
| 43 | #include <boost/tokenizer.hpp>
 | 
|---|
| 44 | #include <iostream>
 | 
|---|
| 45 | #include <string>
 | 
|---|
| 46 | 
 | 
|---|
| 47 | #include "CodePatterns/Assert.hpp"
 | 
|---|
| 48 | #include "CodePatterns/toString.hpp"
 | 
|---|
| 49 | 
 | 
|---|
| 50 | #include "Potentials/Exceptions.hpp"
 | 
|---|
| 51 | 
 | 
|---|
| 52 | SerializablePotential::SerializablePotential() :
 | 
|---|
| 53 |   ParticleTypes()
 | 
|---|
| 54 | {}
 | 
|---|
| 55 | 
 | 
|---|
| 56 | std::ostream& operator<<(std::ostream &ost, const SerializablePotential &potential)
 | 
|---|
| 57 | {
 | 
|---|
| 58 |   potential.stream_to(ost);
 | 
|---|
| 59 |   return ost;
 | 
|---|
| 60 | }
 | 
|---|
| 61 | 
 | 
|---|
| 62 | void SerializablePotential::stream_to(std::ostream &ost) const
 | 
|---|
| 63 | {
 | 
|---|
| 64 |   // check stream
 | 
|---|
| 65 |   if (ost.bad())
 | 
|---|
| 66 |     throw SerializablePotentialException();
 | 
|---|
| 67 | 
 | 
|---|
| 68 |   /// print parameter key
 | 
|---|
| 69 |   ost << getToken() << ":";
 | 
|---|
| 70 |   /// print associated particles
 | 
|---|
| 71 |   const SerializablePotential::ParticleTypes_t &types = getParticleTypes();
 | 
|---|
| 72 |   for (size_t index=0; index < types.size(); ++index) {
 | 
|---|
| 73 |     ost << "\tparticle_type" << index+1 << "=" << types[index];
 | 
|---|
| 74 |     ost << (index != (types.size()-1) ? std::string(",") : std::string(""));
 | 
|---|
| 75 |   }
 | 
|---|
| 76 |   /// print coefficients
 | 
|---|
| 77 |   const SerializablePotential::ParameterNames_t ¶mNames = getParameterNames();
 | 
|---|
| 78 |   const SerializablePotential::parameters_t ¶ms = getParameters();
 | 
|---|
| 79 |   SerializablePotential::ParameterNames_t::const_iterator nameiter = paramNames.begin();
 | 
|---|
| 80 |   SerializablePotential::parameters_t::const_iterator valueiter = params.begin();
 | 
|---|
| 81 |   if (!params.empty()) {
 | 
|---|
| 82 |     if (!types.empty())
 | 
|---|
| 83 |       ost << ",";
 | 
|---|
| 84 |     ost << "\t" << *nameiter << "=" << *valueiter;
 | 
|---|
| 85 |     for (++valueiter, ++nameiter; valueiter != params.end(); ++valueiter, ++nameiter) {
 | 
|---|
| 86 |       ASSERT( nameiter != paramNames.end(),
 | 
|---|
| 87 |           "SerializablePotential::operator<<() - there are less names than parameters.");
 | 
|---|
| 88 |       if (*nameiter != std::string(""))
 | 
|---|
| 89 |         ost << ",\t" << *nameiter << "=" << *valueiter;
 | 
|---|
| 90 |     }
 | 
|---|
| 91 |   }
 | 
|---|
| 92 |   /// print terminating semi-colon
 | 
|---|
| 93 |   ost << ";";
 | 
|---|
| 94 | }
 | 
|---|
| 95 | 
 | 
|---|
| 96 | std::istream& operator>>(std::istream &ist, SerializablePotential &potential)
 | 
|---|
| 97 | {
 | 
|---|
| 98 |   potential.stream_from(ist);
 | 
|---|
| 99 |   return ist;
 | 
|---|
| 100 | }
 | 
|---|
| 101 | 
 | 
|---|
| 102 | void SerializablePotential::stream_from(std::istream &ist)
 | 
|---|
| 103 | {
 | 
|---|
| 104 |   // check stream
 | 
|---|
| 105 |   if (ist.bad())
 | 
|---|
| 106 |     throw SerializablePotentialException();
 | 
|---|
| 107 | 
 | 
|---|
| 108 |   // create copy of current parameters as line may contain not all required
 | 
|---|
| 109 |   SerializablePotential::parameters_t params(getParameters());
 | 
|---|
| 110 | 
 | 
|---|
| 111 |   // read in full line
 | 
|---|
| 112 |   std::string linestring;
 | 
|---|
| 113 |   getline(ist, linestring);
 | 
|---|
| 114 |   const std::string whitespace(" \t");
 | 
|---|
| 115 |   const size_t strBegin = linestring.find_first_not_of(whitespace);
 | 
|---|
| 116 |   const size_t colonpos = linestring.find(":");
 | 
|---|
| 117 |   if ((strBegin == std::string::npos) || (colonpos == std::string::npos) ||
 | 
|---|
| 118 |       (linestring.substr(strBegin, colonpos-strBegin) != getToken()))
 | 
|---|
| 119 |     throw SerializablePotentialMissingValueException()
 | 
|---|
| 120 |         << SerializablePotentialKey(getName());
 | 
|---|
| 121 | 
 | 
|---|
| 122 |   // tokenize by ","
 | 
|---|
| 123 |   typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
 | 
|---|
| 124 |   boost::char_separator<char> pairsep(",\t ;");
 | 
|---|
| 125 |   std::string remainderstring(linestring.substr(colonpos+1));
 | 
|---|
| 126 |   tokenizer tokens(remainderstring, pairsep); //skip colon
 | 
|---|
| 127 | 
 | 
|---|
| 128 |   // step through each token
 | 
|---|
| 129 |   ConvertTo<size_t> ConvertToIndex;
 | 
|---|
| 130 |   ConvertTo<SerializablePotential::parameter_t> ConvertToValue;
 | 
|---|
| 131 |   ConvertTo<SerializablePotential::ParticleType_t> ConvertToParticleType;
 | 
|---|
| 132 |   for (tokenizer::iterator tok_iter = tokens.begin();
 | 
|---|
| 133 |     tok_iter != tokens.end(); ++tok_iter) {
 | 
|---|
| 134 |     const std::string &keyvalue = *tok_iter;
 | 
|---|
| 135 |     const size_t equalitypos = keyvalue.find("=");
 | 
|---|
| 136 |     const std::string key = keyvalue.substr(0,equalitypos);
 | 
|---|
| 137 |     const std::string value = keyvalue.substr(equalitypos+1);
 | 
|---|
| 138 | 
 | 
|---|
| 139 |     /// parse the particle_types
 | 
|---|
| 140 |     const std::string typetoken("particle_type");
 | 
|---|
| 141 |     const size_t pos = key.find(typetoken);
 | 
|---|
| 142 |     if (pos != std::string::npos) {
 | 
|---|
| 143 |       // split of type and convert rest to index
 | 
|---|
| 144 |       const size_t indexpos = pos+typetoken.length();
 | 
|---|
| 145 |       const std::string &indexstring = key.substr(indexpos);
 | 
|---|
| 146 |       const size_t index = ConvertToIndex(indexstring);
 | 
|---|
| 147 |       if(index == 0)
 | 
|---|
| 148 |           throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
| 149 |       // and set the type
 | 
|---|
| 150 |       if (equalitypos == std::string::npos)
 | 
|---|
| 151 |         throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
| 152 |       setParticleType(index-1, ConvertToParticleType(value));
 | 
|---|
| 153 |     } else {
 | 
|---|
| 154 |       const size_t index = getParameterIndex(key);
 | 
|---|
| 155 |       // parse the coefficients
 | 
|---|
| 156 |       if (index != (size_t)-1) {
 | 
|---|
| 157 |         if (equalitypos == std::string::npos)
 | 
|---|
| 158 |           throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
| 159 |         params[index] = ConvertToValue(value);
 | 
|---|
| 160 |       } else {
 | 
|---|
| 161 |         throw SerializablePotentialIllegalKeyException() << SerializablePotentialKey(key);
 | 
|---|
| 162 |       }
 | 
|---|
| 163 |     }
 | 
|---|
| 164 |   }
 | 
|---|
| 165 | 
 | 
|---|
| 166 |   /// set the new paremeters
 | 
|---|
| 167 |   setParameters(params);
 | 
|---|
| 168 | }
 | 
|---|
| 169 | 
 | 
|---|
| 170 | const size_t SerializablePotential::getParameterIndex(const std::string &_name) const
 | 
|---|
| 171 | {
 | 
|---|
| 172 |   const ParameterNames_t& ParameterNames = getParameterNames();
 | 
|---|
| 173 |   ParameterNames_t::const_iterator iter =
 | 
|---|
| 174 |       std::find(ParameterNames.begin(), ParameterNames.end(), _name);
 | 
|---|
| 175 |   if (iter == ParameterNames.end())
 | 
|---|
| 176 |     return (size_t)-1;
 | 
|---|
| 177 |   else
 | 
|---|
| 178 |     return std::distance(ParameterNames.begin(), iter);
 | 
|---|
| 179 | }
 | 
|---|
| 180 | 
 | 
|---|
| 181 | const std::string SerializablePotential::getName() const
 | 
|---|
| 182 | {
 | 
|---|
| 183 |   std::string returnstring = getToken() + std::string("_");
 | 
|---|
| 184 |   BOOST_FOREACH(const ParticleType_t &type, getParticleTypes()) {
 | 
|---|
| 185 |     returnstring += toString(type);
 | 
|---|
| 186 |   }
 | 
|---|
| 187 |   return returnstring;
 | 
|---|
| 188 | }
 | 
|---|