forked from plumed/plumed2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Tools.h
210 lines (187 loc) · 7.22 KB
/
Tools.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 2013 The plumed team
(see the PEOPLE file at the root of the distribution for a list of names)
See http://www.plumed-code.org for more information.
This file is part of plumed, version 2.0.
plumed is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
plumed 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with plumed. If not, see <http://www.gnu.org/licenses/>.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#ifndef __PLUMED_tools_Tools_h
#define __PLUMED_tools_Tools_h
#include "AtomNumber.h"
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <limits>
#include <algorithm>
#include <sstream>
namespace PLMD{
class IFile;
/// \ingroup TOOLBOX
/// Very small non-zero number
const double epsilon(std::numeric_limits<double>::epsilon());
/// \ingroup TOOLBOX
/// Boltzman constant in kj/K
const double kBoltzmann(0.0083144621);
/// \ingroup TOOLBOX
/// PI
const double pi(3.141592653589793238462643383279502884197169399375105820974944592307);
/// \ingroup TOOLBOX
/// Empty class which just contains several (static) tools
class Tools{
public:
/// Split the line in words using separators.
/// It also take into account parenthesis. Outer parenthesis found are removed from
/// output, and the text between them is considered as a single word. Only the
/// outer parenthesis are processed, to allow nesting them.
/// parlevel, if not NULL, is increased or decreased according to the number of opened/closed parenthesis
static std::vector<std::string> getWords(const std::string & line,const char* sep=NULL,int* parlevel=NULL,const char* parenthesis="{");
/// Get a line from the file pointer ifile
static bool getline(FILE*,std::string & line);
/// Get a parsed line from the file pointer ifile
/// This function already takes care of joining continued lines and splitting the
/// resulting line into an array of words
static bool getParsedLine(IFile&ifile,std::vector<std::string> & line);
/// Convert a string to a double, reading it
static bool convert(const std::string & str,double & t);
/// Convert a string to a float, reading it
static bool convert(const std::string & str,float & t);
/// Convert a string to a int, reading it
static bool convert(const std::string & str,int & t);
/// Convert a string to a long int, reading it
static bool convert(const std::string & str,long int & t);
/// Convert a string to an unsigned int, reading it
static bool convert(const std::string & str,unsigned & t);
/// Convert a string to a atom number, reading it
static bool convert(const std::string & str,AtomNumber & t);
/// Convert a string to a string (i.e. copy)
static bool convert(const std::string & str,std::string & t);
/// Convert anything into a string
template<typename T>
static void convert(T i,std::string & str);
/// Remove trailing blanks
static void trim(std::string & s);
/// Remove trailing comments
static void trimComments(std::string & s);
/// Apply pbc for a unitary cell
static double pbc(double);
/// Retrieve a key from a vector of options.
/// It finds a key starting with "key=" or equal to "key" and copy the
/// part after the = on s. E.g.:
/// line.push_back("aa=xx");
/// getKey(line,"aa",s);
/// will set s="xx"
static bool getKey(std::vector<std::string>& line,const std::string & key,std::string & s);
/// Find a keyword on the input line, eventually deleting it, and saving its value to val
template <class T>
static bool parse(std::vector<std::string>&line,const std::string&key,T&val);
/// Find a keyword on the input line, eventually deleting it, and saving its value to a vector
template <class T>
static bool parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val);
/// Find a keyword without arguments on the input line
static bool parseFlag(std::vector<std::string>&line,const std::string&key,bool&val);
/// Interpret atom ranges
static void interpretRanges(std::vector<std::string>&);
/// Remove duplicates from a vector of type T
template <typename T>
static void removeDuplicates(std::vector<T>& vec);
/// interpret ":" syntax for labels
static void interpretLabel(std::vector<std::string>&s);
/// list files in a directory
static std::vector<std::string> ls(const std::string&);
/// removes leading and trailing blanks from a string
static void stripLeadingAndTrailingBlanks( std::string& str );
/// Extract the extensions from a file name.
/// E.g.: extension("pippo.xyz")="xyz".
/// It only returns extensions with a length between 1 and 4
/// E.g.: extension("pippo.12345")="" whereas extenion("pippo.1234")="1234";
/// It is also smart enough to detect "/", so that
/// extension("pippo/.t")="" whereas extension("pippo/a.t")="t"
static std::string extension(const std::string&);
/// Fast int power
static double fastpow(double base,int exp);
};
template <class T>
bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val){
std::string s;
if(!getKey(line,key+"=",s)) return false;
if(s.length()>0 && !convert(s,val))return false;
return true;
}
template <class T>
bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val){
std::string s;
if(!getKey(line,key+"=",s)) return false;
// if(s.length()==0) return true;
val.clear();
std::vector<std::string> words=getWords(s,"\t\n ,");
for(unsigned i=0;i<words.size();++i){
T v;
if(!convert(words[i],v))return false;
val.push_back(v);
}
return true;
}
template<typename T>
void Tools::removeDuplicates(std::vector<T>& vec)
{
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
}
inline
bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val){
for(std::vector<std::string>::iterator p=line.begin();p!=line.end();++p){
if(key==*p){
val=true;
line.erase(p);
return true;
}
}
return false;
}
/// beware: this brings any number into a pbc that ranges from -0.5 to 0.5
inline
double Tools::pbc(double x){
if(std::numeric_limits<int>::round_style == std::round_toward_zero) {
const double offset=100.0;
const double y=x+offset;
if(y>=0) return y-int(y+0.5);
else return y-int(y-0.5);
} else if(std::numeric_limits<int>::round_style == std::round_to_nearest) {
return x-int(x);
} else return x-floor(x+0.5);
}
template<typename T>
void Tools::convert(T i,std::string & str){
std::ostringstream ostr;
ostr<<i;
str=ostr.str();
}
inline
double Tools::fastpow(double base, int exp)
{
if(exp<0){
exp=-exp;
base=1.0/base;
}
double result = 1.0;
while (exp)
{
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
}
#endif