LOOS 4.1.0
The Lightweight Object Oriented Structural analysis library/toolkit
Loading...
Searching...
No Matches
utils.hpp
1/*
2 This file is part of LOOS.
3
4 LOOS (Lightweight Object-Oriented Structure library)
5 Copyright (c) 2008, Tod D. Romo, Alan Grossfield
6 Department of Biochemistry and Biophysics
7 School of Medicine & Dentistry, University of Rochester
8
9 This package (LOOS) is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation under version 3 of the License.
12
13 This package is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#if !defined(LOOS_UTILS_HPP)
23#define LOOS_UTILS_HPP
24
25#include <iostream>
26#include <sstream>
27#include <fstream>
28#include <iterator>
29#include <algorithm>
30#include <string>
31#include <vector>
32#include <set>
33#include <exception>
34#include <stdexcept>
35
36#include <boost/algorithm/string.hpp>
37#include <boost/any.hpp>
38#include <boost/lexical_cast.hpp>
39#include <boost/program_options.hpp>
40
41#include <ctime>
42
43#include <loos_defs.hpp>
44#include <exceptions.hpp>
45#include <Coord.hpp>
46#include <pdb_remarks.hpp>
47#include <LineReader.hpp>
48
50namespace loos
51{
52
54 std::string findBaseName(const std::string &);
55
56 boost::tuple<std::string, std::string> splitFilename(const std::string &filename);
57
59 std::string getNextLine(std::istream &is, int *lineno);
60
62
70 template <typename T>
71 std::vector<T> readVector(LineReader &reader)
72 {
73 std::vector<T> data;
74 while (reader.getNext())
75 {
76 std::istringstream iss(reader.line());
77 T datum;
78 iss >> datum;
79 data.push_back(datum);
80 }
81
82 return (data);
83 }
84
86 template <typename T>
87 std::vector<T> readVector(std::istream &is)
88 {
89 LineReader lr(is);
90 return (readVector<T>(lr));
91 }
92
94 template <typename T>
95 std::vector<T> readVector(const std::string &fname)
96 {
97 std::ifstream ifs(fname.c_str());
98 LineReader lr(ifs, fname);
99 return (readVector<T>(lr));
100 }
101
103
108 template <typename T>
109 std::vector<std::vector<T>> readTable(LineReader &reader)
110 {
111 std::vector<std::vector<T>> table;
112
113 while (reader.getNext())
114 {
115 if (reader.line().empty())
116 break;
117
118 std::istringstream iss(reader.line());
119 T datum;
120 std::vector<T> row;
121 while (iss >> datum)
122 row.push_back(datum);
123 table.push_back(row);
124 }
125 return (table);
126 }
127
129 template <typename T>
130 std::vector<std::vector<T>> readTable(std::istream &is)
131 {
132 LineReader lr(is);
133 return (readTable<T>(lr));
134 }
135
137 template <typename T>
138 std::vector<std::vector<T>> readTable(const std::string &fname)
139 {
140 std::ifstream ifs(fname.c_str());
141 LineReader lr(ifs, fname);
142 return (readTable<T>(lr));
143 }
144
146
150 std::string invocationHeader(int, char *[]);
151
153
167 template <typename T>
168 std::vector<T> parseRange(const std::string &text, const T endpoint = 0)
169 {
170 T a;
171 T b;
172 T c;
173 char sep;
174 std::vector<T> indices;
175 std::istringstream is(text);
176
177 is >> a;
178 if (is.eof())
179 {
180 indices.push_back(a);
181 return (indices);
182 }
183
184 sep = is.get();
185 bool is_negative = false;
186
187 if (is.peek() == '*')
188 {
189 b = endpoint;
190 is.get();
191 }
192 else
193 {
194 if (is.peek() == '-')
195 {
196 is_negative = true;
197 is.get();
198 }
199 is >> b;
200 if (is.fail() || sep != ':')
201 throw(ParseError("Could not parse range (1) " + text));
202 }
203
204 sep = is.get();
205 if (is.eof())
206 {
207 c = 1;
208 if (is_negative)
209 b = -b;
210
211 is_negative = a > b;
212 }
213 else
214 {
215 if (sep != ':')
216 throw(ParseError("Could not parse range (2) " + text));
217 c = b;
218 if (is.peek() == '*')
219 {
220 b = endpoint;
221 is.get();
222 }
223 else
224 {
225 is >> b;
226 if (is.fail())
227 throw(ParseError("Could not parse range (3) " + text));
228 }
229 }
230
231 // Some input validation...
232 if (a > b && !is_negative)
233 throw(ParseError("You must use a negative step to count down: " + text));
234 if (a < b && is_negative)
235 throw(ParseError("You must use a postive step to count up: " + text));
236 if (c == 0)
237 throw(ParseError("Thou shalt only use non-zero step sizes: " + text));
238
239 if (is_negative)
240 {
241
242 T i;
243 for (i = a; i > b; i -= c)
244 indices.push_back(i);
245 if (a < -a && b == 0) // If unsigned type, cannot use >= 0 as test
246 indices.push_back(0);
247 else if (i >= b)
248 indices.push_back(i);
249 }
250 else
251 for (T i = a; i <= b; i += c)
252 indices.push_back(i);
253
254 return (indices);
255 }
256
258
265 template <typename T>
266 std::vector<T> parseRangeList(const std::string &text, const T endpoint = 0)
267 {
268 std::vector<std::string> terms;
269 std::set<T> indices;
270 std::insert_iterator<std::set<T>> ii(indices, indices.begin());
271
272 boost::split(terms, text, boost::is_any_of(","), boost::token_compress_on);
273 std::vector<std::string>::const_iterator ci;
274 for (ci = terms.begin(); ci != terms.end(); ci++)
275 {
276 if (ci->empty())
277 continue;
278 std::vector<T> result = parseRange<T>(*ci, endpoint);
279 std::copy(result.begin(), result.end(), ii);
280 }
281 std::vector<T> results(indices.size());
282 std::copy(indices.begin(), indices.end(), results.begin());
283 return (results);
284 }
285
287 std::vector<int> parseRangeList(const std::string &, const int endpoint = 0);
288
290 template <typename T>
291 std::vector<T> parseRangeList(const std::vector<std::string> &ranges, const T endpoint = 0)
292 {
293 std::ostringstream os;
294 std::copy(ranges.begin(), ranges.end(), std::ostream_iterator<std::string>(os, ","));
295 return (parseRangeList<T>(os.str(), endpoint));
296 }
297
299 AtomicGroup selectAtoms(const AtomicGroup &, const std::string);
300
302
305 template <typename T>
306 T swab(const T &datum)
307 {
308 uint size = sizeof(T);
309 const unsigned char *p = reinterpret_cast<const unsigned char *>(&datum);
310 T swabbed;
311 unsigned char *q = reinterpret_cast<unsigned char *>(&swabbed);
312
313 uint i, j;
314 for (i = 0, j = size - 1; i < size; ++i, --j)
315 q[i] = p[j];
316
317 return (swabbed);
318 }
319
321 std::string timeAsString(const double t, const uint precision = 0);
322
324 template <typename T>
325 T parseStringAs(const std::string &source, const uint pos = 0, const uint nelem = 0)
326 {
327 T val(0);
328
329 if (pos >= source.size())
330 {
331 std::stringstream msg;
332 msg << "Missing Field at position " << pos << std::endl;
333 msg << "> " << source << std::endl;
334 throw(ParseError(msg.str()));
335 }
336
337 uint n = !nelem ? source.size() - pos : nelem;
338 if (pos + n > source.size())
339 n = source.size() - pos + 1;
340
341 std::string element(source.substr(pos, n));
342 std::istringstream iss(element);
343 if (!(iss >> val))
344 {
345 std::stringstream msg;
346 msg << "PARSE ERROR\n"
347 << source << std::endl;
348 for (uint i = 0; i < pos; ++i)
349 msg << ' ';
350 msg << '^';
351 if (n > 1)
352 for (uint i = 1; i < n; ++i)
353 msg << '^';
354 msg << std::endl;
355 throw(ParseError(msg.str()));
356 }
357
358 return (val);
359 }
360
361 template <>
362 std::string parseStringAs<std::string>(const std::string &source, const uint pos, const uint nelem);
363
364 template <typename T>
365 std::string fixedSizeFormat(const T t, const uint n)
366 {
367 std::stringstream ss;
368 ss << t;
369 std::string s(ss.str());
370 uint m = s.size();
371 if (m > n)
372 return (s.substr(m - n, n));
373 return (s);
374 }
375
376 template <>
377 std::string fixedSizeFormat(const std::string &s, const uint n);
378
380 int parseStringAsHybrid36(const std::string &source, const uint pos = 0, const uint nelem = 0);
381
383 std::string hybrid36AsString(int value, uint fieldsize);
384
385 // The following are for support of boost::program_options
386
388 template <typename T>
389 std::string vToString(const T &x)
390 {
391 std::ostringstream oss;
392
393 for (typename T::const_iterator i = x.begin(); i != x.end(); ++i)
394 oss << *i << ((i == x.end() - 1) ? "" : ",");
395
396 return (oss.str());
397 }
398
400 std::string sanitizeString(const std::string &s);
401
403 std::string stringsAsComments(const std::vector<std::string> &v);
404
406 std::string stringsAsString(const std::vector<std::string> &v);
407
409 template <typename T>
410 std::string vectorAsStringWithCommas(const std::vector<T> &v)
411 {
412 std::ostringstream oss;
413 for (typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
414 {
415 oss << *i;
416 if (i != v.end() - 1)
417 oss << ",";
418 }
419 return (oss.str());
420 }
421
422 template <>
423 std::string vectorAsStringWithCommas(const std::vector<std::string> &v);
424
426 template <typename T>
427 std::vector<T> uniquifyVector(const std::vector<T> &list)
428 {
429 std::set<T> indices;
430 std::insert_iterator<std::set<T>> ii(indices, indices.begin());
431 std::copy(list.begin(), list.end(), ii);
432
433 std::vector<T> uniques(indices.size());
434 std::copy(indices.begin(), indices.end(), uniques.begin());
435 return uniques;
436 }
437
438 long availableMemory();
439
440};
441
442#endif
Class for reading line-by-line from a file while tracking line numbers and stripping comments.
Definition LineReader.hpp:39
virtual bool getNext()
Get the next line from the file, returning true if successful.
Definition LineReader.cpp:38
virtual std::string line() const
The currently read line.
Definition LineReader.cpp:62
Exception when parsing input data.
Definition exceptions.hpp:69
Namespace for most things not already encapsulated within a class.
Definition version.cpp:3
AtomicGroup selectAtoms(const AtomicGroup &source, const std::string selection)
Applies a string-based selection to an atomic group...
Definition utils.cpp:183
std::string findBaseName(const std::string &s)
Pull off the file name extension (if present)
Definition utils.cpp:61
std::vector< T > readVector(LineReader &reader)
Read a list of items using a LineReader object.
Definition utils.hpp:71
std::string stringsAsString(const std::vector< std::string > &v)
Converts a vector of strings into a single string with newlines.
Definition utils.cpp:403
std::string getNextLine(std::istream &is, int *lineno=0)
Get the next line of input, skipping blanks and stripping comments.
Definition utils.cpp:88
std::vector< T > uniquifyVector(const std::vector< T > &list)
Return a vector containing only the unique elements of the input vector.
Definition utils.hpp:427
std::vector< int > parseRangeList(const std::string &text, const int endpoint)
Parses a list of Octave-style range specifiers (for compatability)
Definition utils.cpp:166
int parseStringAsHybrid36(const std::string &source, const uint pos, const uint nelem)
Convert a hybrid-36 encoded string into an int.
Definition utils.cpp:259
std::string stringsAsComments(const std::vector< std::string > &v)
Converts a vector of strings into a standard log format.
Definition utils.cpp:393
std::string vectorAsStringWithCommas(const std::vector< std::string > &v)
Specialization for strings that sanitizes the contained strings.
Definition utils.cpp:418
T parseStringAs(const std::string &source, const uint pos=0, const uint nelem=0)
Extracts a field from a string.
Definition utils.hpp:325
std::string sanitizeString(const std::string &s)
Removes internal newlines from string.
Definition utils.cpp:380
std::vector< std::vector< T > > readTable(LineReader &reader)
Read in a table of items using a LineReader object.
Definition utils.hpp:109
std::vector< T > parseRange(const std::string &text, const T endpoint=0)
Parse an Octave/Matlab-style range.
Definition utils.hpp:168
std::string invocationHeader(int argc, char *argv[])
Create an invocation header.
Definition utils.cpp:119
std::string timeAsString(const double t, const uint precision)
Convert t (seconds) into a string, converting to hours and minutes as necessary.
Definition utils.cpp:203
std::string hybrid36AsString(int d, uint n)
Convert an int into a hybrid-36 encoded string.
Definition utils.cpp:320
std::string vToString(const T &x)
Convert something that can iterate into a string...
Definition utils.hpp:389
T swab(const T &datum)
Returns a byte-swapped copy of an arbitrary type.
Definition utils.hpp:306