LOOS  v2.3.2
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 
23 
24 
25 #if !defined(LOOS_UTILS_HPP)
26 #define LOOS_UTILS_HPP
27 
28 #include <iostream>
29 #include <sstream>
30 #include <fstream>
31 #include <iterator>
32 #include <algorithm>
33 #include <string>
34 #include <vector>
35 #include <set>
36 #include <exception>
37 #include <stdexcept>
38 
39 
40 #include <boost/algorithm/string.hpp>
41 #include <boost/any.hpp>
42 #include <boost/lexical_cast.hpp>
43 #include <boost/program_options.hpp>
44 
45 #include <ctime>
46 
47 
48 #include <loos_defs.hpp>
49 #include <exceptions.hpp>
50 #include <Coord.hpp>
51 #include <pdb_remarks.hpp>
52 #include <LineReader.hpp>
53 
54 
55 
57 namespace loos {
58 
60  std::string findBaseName(const std::string&);
61 
62  boost::tuple<std::string, std::string> splitFilename(const std::string& filename);
63 
65  std::string getNextLine(std::istream& is, int* lineno);
66 
68 
76  template<typename T>
77  std::vector<T> readVector(LineReader& reader) {
78  std::vector<T> data;
79  while (reader.getNext()) {
80  std::istringstream iss(reader.line());
81  T datum;
82  iss >> datum;
83  data.push_back(datum);
84  }
85 
86  return(data);
87  }
88 
90  template<typename T>
91  std::vector<T> readVector(std::istream& is) {
92  LineReader lr(is);
93  return(readVector<T>(lr));
94  }
95 
97  template<typename T>
98  std::vector<T> readVector(const std::string& fname) {
99  std::ifstream ifs(fname.c_str());
100  LineReader lr(ifs, fname);
101  return(readVector<T>(lr));
102  }
103 
104 
105 
106 
108 
113  template<typename T>
114  std::vector< std::vector<T> > readTable(LineReader& reader) {
115  std::vector< std::vector<T> > table;
116 
117  while (reader.getNext()) {
118  if (reader.line().empty())
119  break;
120 
121  std::istringstream iss(reader.line());
122  T datum;
123  std::vector<T> row;
124  while (iss >> datum)
125  row.push_back(datum);
126  table.push_back(row);
127  }
128  return(table);
129  }
130 
132  template<typename T>
133  std::vector< std::vector<T> > readTable(std::istream& is) {
134  LineReader lr(is);
135  return(readTable<T>(lr));
136  }
137 
139  template<typename T>
140  std::vector< std::vector<T> > readTable(const std::string& fname) {
141  std::ifstream ifs(fname.c_str());
142  LineReader lr(ifs, fname);
143  return(readTable<T>(lr));
144  }
145 
147 
151  std::string invocationHeader(int, char *[]);
152 
153 
154 
155 
156 
158 
172  template<typename T>
173  std::vector<T> parseRange(const std::string& text) {
174  T a;
175  T b;
176  T c;
177  char sep;
178  std::vector<T> indices;
179  std::istringstream is(text);
180 
181  is >> a;
182  if (is.eof()) {
183  indices.push_back(a);
184  return(indices);
185  }
186 
187  is >> sep;
188  bool is_negative = false;
189  if (is.peek() == '-') {
190  is_negative = true;
191  is.get();
192  }
193  is >> b;
194  if (is.fail() || sep != ':')
195  throw(ParseError("Could not parse range " + text));
196 
197  if (is.eof()) {
198  c = 1;
199  if (is_negative)
200  b = -b;
201 
202  is_negative = a > b;
203 
204  } else {
205  c = b;
206  is >> sep >> b;
207  if (is.fail() || sep != ':')
208  throw(ParseError("Could not parse range " + text));
209  }
210 
211  // Some input validation...
212  if (a > b && !is_negative)
213  throw(ParseError("You must use a negative step to count down: " + text));
214  if (a < b && is_negative)
215  throw(ParseError("You must use a postive step to count up: " + text));
216  if (c == 0)
217  throw(ParseError("Thou shalt only use non-zero step sizes: " + text));
218 
219  if (is_negative) {
220 
221  T i;
222  for (i=a; i > b; i -= c)
223  indices.push_back(i);
224  if (a < -a && b == 0) // If unsigned type, cannot use >= 0 as test
225  indices.push_back(0);
226  else if (i >= b)
227  indices.push_back(i);
228 
229  } else
230  for (T i=a; i <= b; i += c)
231  indices.push_back(i);
232 
233  return(indices);
234  }
235 
236 
237 
238 
240 
247  template<typename T>
248  std::vector<T> parseRangeList(const std::string& text) {
249  std::vector<std::string> terms;
250  std::set<T> indices;
251  std::insert_iterator< std::set<T> > ii(indices, indices.begin());
252 
253  boost::split(terms, text, boost::is_any_of(","), boost::token_compress_on);
254  std::vector<std::string>::const_iterator ci;
255  for (ci = terms.begin(); ci != terms.end(); ci++) {
256  if (ci->empty())
257  continue;
258  std::vector<T> result = parseRange<T>(*ci);
259  std::copy(result.begin(), result.end(), ii);
260  }
261  std::vector<T> results(indices.size());
262  std::copy(indices.begin(), indices.end(), results.begin());
263  return(results);
264  }
265 
266 
268  std::vector<int> parseRangeList(const std::string&);
269 
271  template<typename T>
272  std::vector<T> parseRangeList(const std::vector<std::string>& ranges) {
273  std::ostringstream os;
274  std::copy(ranges.begin(), ranges.end(), std::ostream_iterator<std::string>(os, ","));
275  return(parseRangeList<T>(os.str()));
276  }
277 
279  AtomicGroup selectAtoms(const AtomicGroup&, const std::string);
280 
281 
283 
286  template<typename T>
287  T swab(const T& datum) {
288  uint size = sizeof(T);
289  const unsigned char* p = reinterpret_cast<const unsigned char*>(&datum);
290  T swabbed;
291  unsigned char* q = reinterpret_cast<unsigned char*>(&swabbed);
292 
293  uint i, j;
294  for (i=0, j=size-1; i<size; ++i, --j)
295  q[i] = p[j];
296 
297  return(swabbed);
298  }
299 
300 
302  std::string timeAsString(const double t, const uint precision = 0);
303 
305  template<typename T>
306  T parseStringAs(const std::string& source, const uint pos =0, const uint nelem =0) {
307  T val(0);
308 
309  if (pos >= source.size()) {
310  std::stringstream msg;
311  msg << "Missing Field at position " << pos << std::endl;
312  msg << "> " << source << std::endl;
313  throw(ParseError(msg.str()));
314  }
315 
316  uint n = !nelem ? source.size() - pos : nelem;
317  if (pos + n > source.size())
318  n = source.size() - pos + 1;
319 
320 
321 
322  std::string element(source.substr(pos, n));
323  std::istringstream iss(element);
324  if (!(iss >> val)) {
325  std::stringstream msg;
326  msg << "PARSE ERROR\n" << source << std::endl;
327  for (uint i=0; i<pos; ++i)
328  msg << ' ';
329  msg << '^';
330  if (n > 1)
331  for (uint i=1; i<n; ++i)
332  msg << '^';
333  msg << std::endl;
334  throw(ParseError(msg.str()));
335  }
336 
337  return(val);
338  }
339 
340  template<> std::string parseStringAs<std::string>(const std::string& source, const uint pos, const uint nelem);
341 
342  template<typename T>
343  std::string fixedSizeFormat(const T t, const uint n) {
344  std::stringstream ss;
345  ss << t;
346  std::string s(ss.str());
347  uint m = s.size();
348  if (m > n)
349  return(s.substr(m-n, n));
350  return(s);
351  }
352 
353  template<> std::string fixedSizeFormat(const std::string& s, const uint n);
354 
356  int parseStringAsHybrid36(const std::string& source, const uint pos =0, const uint nelem =0);
357 
359  std::string hybrid36AsString(int value, uint fieldsize);
360 
361  // The following are for support of boost::program_options
362 
364  template<typename T> std::string vToString(const T& x) {
365  std::ostringstream oss;
366 
367  for (typename T::const_iterator i = x.begin(); i != x.end(); ++i)
368  oss << *i << ((i == x.end() - 1) ? "" : ",");
369 
370  return(oss.str());
371  }
372 
373 
375  std::string sanitizeString(const std::string& s);
376 
378  std::string stringsAsComments(const std::vector<std::string>& v);
379 
380 
382  std::string stringsAsString(const std::vector<std::string>& v);
383 
384 
385 
387  template<typename T> std::string vectorAsStringWithCommas(const std::vector<T>& v) {
388  std::ostringstream oss;
389  for (typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i) {
390  oss << *i;
391  if (i != v.end() - 1)
392  oss << ",";
393  }
394  return(oss.str());
395  }
396 
397  template<> std::string vectorAsStringWithCommas(const std::vector<std::string>& v);
398 
399 
400  long availableMemory();
401 
402 };
403 
404 #endif
virtual std::string line() const
The currently read line.
Definition: LineReader.cpp:62
std::vector< std::vector< T > > readTable(LineReader &reader)
Read in a table of items using a LineReader object.
Definition: utils.hpp:114
std::string hybrid36AsString(int d, uint n)
Convert an int into a hybrid-36 encoded string.
Definition: utils.cpp:322
T swab(const T &datum)
Returns a byte-swapped copy of an arbitrary type.
Definition: utils.hpp:287
Class for reading line-by-line from a file while tracking line numbers and stripping comments...
Definition: LineReader.hpp:39
std::string invocationHeader(int argc, char *argv[])
Create an invocation header.
Definition: utils.cpp:124
AtomicGroup selectAtoms(const AtomicGroup &source, const std::string selection)
Applies a string-based selection to an atomic group...
Definition: utils.cpp:195
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:212
std::string getNextLine(std::istream &is, int *lineno=0)
Get the next line of input, skipping blanks and stripping comments.
Definition: utils.cpp:93
std::vector< T > readVector(LineReader &reader)
Read a list of items using a LineReader object.
Definition: utils.hpp:77
Exception when parsing input data.
Definition: exceptions.hpp:64
std::string findBaseName(const std::string &s)
Pull off the file name extension (if present)
Definition: utils.cpp:68
Namespace for most things not already encapsulated within a class.
std::string stringsAsString(const std::vector< std::string > &v)
Converts a vector of strings into a single string with newlines.
Definition: utils.cpp:401
std::vector< T > parseRange(const std::string &text)
Parse an Octave/Matlab-style range.
Definition: utils.hpp:173
std::string stringsAsComments(const std::vector< std::string > &v)
Converts a vector of strings into a standard log format.
Definition: utils.cpp:391
std::string sanitizeString(const std::string &s)
Removes internal newlines from string.
Definition: utils.cpp:378
std::string vectorAsStringWithCommas(const std::vector< std::string > &v)
Specialization for strings that sanitizes the contained strings.
Definition: utils.cpp:415
T parseStringAs(const std::string &source, const uint pos=0, const uint nelem=0)
Extracts a field from a string.
Definition: utils.hpp:306
virtual bool getNext()
Get the next line from the file, returning true if successful.
Definition: LineReader.cpp:38
std::vector< int > parseRangeList(const std::string &text)
Parses a comma-separated list of Octave-style ranges.
Definition: utils.cpp:179
std::string vToString(const T &x)
Convert something that can iterate into a string...
Definition: utils.hpp:364
int parseStringAsHybrid36(const std::string &source, const uint pos, const uint nelem)
Convert a hybrid-36 encoded string into an int.
Definition: utils.cpp:266