LCOV - code coverage report
Current view: top level - tools - Tools.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 40 42 95.2 %
Date: 2021-11-18 15:22:58 Functions: 18 19 94.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2020 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_Tools_h
      23             : #define __PLUMED_tools_Tools_h
      24             : 
      25             : #include "AtomNumber.h"
      26             : #include <vector>
      27             : #include <string>
      28             : #include <cstdio>
      29             : #include <cmath>
      30             : #include <limits>
      31             : #include <algorithm>
      32             : #include <sstream>
      33             : #include <memory>
      34             : 
      35             : namespace PLMD {
      36             : 
      37             : class IFile;
      38             : 
      39             : /// \ingroup TOOLBOX
      40             : /// Very small non-zero number
      41             : const double epsilon(std::numeric_limits<double>::epsilon());
      42             : 
      43             : /// \ingroup TOOLBOX
      44             : /// Boltzman constant in kj/K
      45             : const double kBoltzmann(0.0083144621);
      46             : 
      47             : /// \ingroup TOOLBOX
      48             : /// PI
      49             : const double pi(3.141592653589793238462643383279502884197169399375105820974944592307);
      50             : 
      51             : /// \ingroup TOOLBOX
      52             : /// Empty class which just contains several (static) tools
      53             : class Tools {
      54             : /// class to convert a string to a generic type T
      55             :   template<class T>
      56             :   static bool convertToAny(const std::string & str,T &t);
      57             : /// class to convert a string to a real type T.
      58             : /// T should be either float, double, or long double
      59             :   template<class T>
      60             :   static bool convertToReal(const std::string & str,T &t);
      61             : public:
      62             : /// Split the line in words using separators.
      63             : /// It also take into account parenthesis. Outer parenthesis found are removed from
      64             : /// output, and the text between them is considered as a single word. Only the
      65             : /// outer parenthesis are processed, to allow nesting them.
      66             : /// parlevel, if not NULL, is increased or decreased according to the number of opened/closed parenthesis
      67             :   static std::vector<std::string> getWords(const std::string & line,const char* sep=NULL,int* parlevel=NULL,const char* parenthesis="{");
      68             : /// Get a line from the file pointer ifile
      69             :   static bool getline(FILE*,std::string & line);
      70             : /// Get a parsed line from the file pointer ifile
      71             : /// This function already takes care of joining continued lines and splitting the
      72             : /// resulting line into an array of words
      73             :   static bool getParsedLine(IFile&ifile,std::vector<std::string> & line);
      74             : /// Convert a string to a double, reading it
      75             :   static bool convert(const std::string & str,double & t);
      76             : /// Convert a string to a long double, reading it
      77             :   static bool convert(const std::string & str,long double & t);
      78             : /// Convert a string to a float, reading it
      79             :   static bool convert(const std::string & str,float & t);
      80             : /// Convert a string to a int, reading it
      81             :   static bool convert(const std::string & str,int & t);
      82             : /// Convert a string to a long int, reading it
      83             :   static bool convert(const std::string & str,long int & t);
      84             : /// Convert a string to an unsigned int, reading it
      85             :   static bool convert(const std::string & str,unsigned & t);
      86             : /// Convert a string to a atom number, reading it
      87             :   static bool convert(const std::string & str,AtomNumber & t);
      88             : /// Convert a string to a string (i.e. copy)
      89             :   static bool convert(const std::string & str,std::string & t);
      90             : /// Convert anything into a string
      91             :   template<typename T>
      92             :   static void convert(T i,std::string & str);
      93             : /// Remove trailing blanks
      94             :   static void trim(std::string & s);
      95             : /// Remove trailing comments
      96             :   static void trimComments(std::string & s);
      97             : /// Apply pbc for a unitary cell
      98             :   static double pbc(double);
      99             : /// Retrieve a key from a vector of options.
     100             : /// It finds a key starting with "key=" or equal to "key" and copy the
     101             : /// part after the = on s. E.g.:
     102             : /// line.push_back("aa=xx");
     103             : /// getKey(line,"aa",s);
     104             : /// will set s="xx"
     105             :   static bool getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep=-1);
     106             : /// Find a keyword on the input line, eventually deleting it, and saving its value to val
     107             :   template <class T>
     108             :   static bool parse(std::vector<std::string>&line,const std::string&key,T&val,int rep=-1);
     109             : /// Find a keyword on the input line, eventually deleting it, and saving its value to a vector
     110             :   template <class T>
     111             :   static bool parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep=-1);
     112             : /// Find a keyword without arguments on the input line
     113             :   static bool parseFlag(std::vector<std::string>&line,const std::string&key,bool&val);
     114             : /// Find a keyword on the input line, just reporting if it exists or not
     115             :   static bool findKeyword(const std::vector<std::string>&line,const std::string&key);
     116             : /// Interpret atom ranges
     117             :   static void interpretRanges(std::vector<std::string>&);
     118             : /// Remove duplicates from a vector of type T
     119             :   template <typename T>
     120             :   static void removeDuplicates(std::vector<T>& vec);
     121             : /// interpret ":" syntax for labels
     122             :   static void interpretLabel(std::vector<std::string>&s);
     123             : /// list files in a directory
     124             :   static std::vector<std::string> ls(const std::string&);
     125             : /// removes leading and trailing blanks from a string
     126             :   static void stripLeadingAndTrailingBlanks( std::string& str );
     127             : /// Extract the extensions from a file name.
     128             : /// E.g.: extension("pippo.xyz")="xyz".
     129             : /// It only returns extensions with a length between 1 and 4
     130             : /// E.g.: extension("pippo.12345")="" whereas extenion("pippo.1234")="1234";
     131             : /// It is also smart enough to detect "/", so that
     132             : /// extension("pippo/.t")="" whereas extension("pippo/a.t")="t"
     133             :   static std::string extension(const std::string&);
     134             : /// Fast int power
     135             :   static double fastpow(double base,int exp);
     136             : /// Modified 0th-order Bessel function of the first kind
     137             :   static double bessel0(const double& val);
     138             : /// Check if a string full starts with string start.
     139             : /// Same as full.find(start)==0
     140             :   static bool startWith(const std::string & full,const std::string &start);
     141             :   /**
     142             :     Tool to create a vector of raw pointers from a vector of unique_pointers (const version).
     143             :   Returning a vector is fast in C++11. It can be used in order to feed a vector<unique_ptr<T>>
     144             :   to a function that takes a vector<T*>.
     145             :   \verbatim
     146             :   // some function that takes a vec
     147             :   void func(std::vector<Data*> & vec);
     148             :   std::vector<std::unique_ptr<Data>> vec;
     149             :   // func(vec); // does not compile
     150             :   func(Tools::unique2raw(vec)); // compiles
     151             :   \endverbatim
     152             :   Notice that the conversion is fast but takes
     153             :   some time to allocate the new vector and copy the pointers. In case the function
     154             :   acting on the vector<T*> is very fast and we do not want to add significant overhead,
     155             :   it might be convenient to store a separate set of raw pointers.
     156             :   \verbatim
     157             :   // some function that takes a vec
     158             :   void func(std::vector<Data*> & vec);
     159             :   std::vector<std::unique_ptr<Data>> vec;
     160             : 
     161             :   // conversion done only once:
     162             :   auto vec_ptr=Tools::unique2raw(vec);
     163             : 
     164             :   for(int i=0;i<1000;i++){
     165             :     func(vec_ptr);
     166             :   }
     167             :   \endverbatim
     168             :   */
     169             :   template <typename T>
     170             :   static std::vector<T*> unique2raw(const std::vector<std::unique_ptr<T>>&);
     171             : /// Tool to create a vector of raw pointers from a vector of unique_pointers.
     172             : /// See the non const version.
     173             :   template <typename T>
     174             :   static std::vector<const T*> unique2raw(const std::vector<std::unique_ptr<const T>>&);
     175             : /// Tiny class that changes directory and comes back when going out of scope.
     176             : /// In case system calls to change dir are not available it throws an exception.
     177             : /// \warning By construction, changing directory breaks thread safety! Use with care.
     178             :   class DirectoryChanger {
     179             :     static const size_t buffersize=4096;
     180             :     char cwd[buffersize]= {0};
     181             :   public:
     182             :     explicit DirectoryChanger(const char*path);
     183             :     ~DirectoryChanger();
     184             :   };
     185             : };
     186             : 
     187             : template <class T>
     188       42017 : bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val,int rep) {
     189             :   std::string s;
     190       84034 :   if(!getKey(line,key+"=",s,rep)) return false;
     191       18076 :   if(s.length()>0 && !convert(s,val))return false;
     192             :   return true;
     193             : }
     194             : 
     195             : template <class T>
     196       18301 : bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep) {
     197             :   std::string s;
     198       36602 :   if(!getKey(line,key+"=",s,rep)) return false;
     199        8154 :   val.clear();
     200       21110 :   std::vector<std::string> words=getWords(s,"\t\n ,");
     201       83297 :   for(unsigned i=0; i<words.size(); ++i) {
     202             :     T v;
     203             :     std::string s=words[i];
     204       20729 :     const std::string multi("@replicas:");
     205       20729 :     if(rep>=0 && startWith(s,multi)) {
     206          12 :       s=s.substr(multi.length(),s.length());
     207          12 :       std::vector<std::string> words=getWords(s,"\t\n ,");
     208           6 :       plumed_assert(rep<static_cast<int>(words.size()));
     209           6 :       s=words[rep];
     210             :     }
     211       20729 :     if(!convert(s,v))return false;
     212       20729 :     val.push_back(v);
     213             :   }
     214             :   return true;
     215             : }
     216             : 
     217             : template<typename T>
     218         172 : void Tools::removeDuplicates(std::vector<T>& vec)
     219             : {
     220             :   std::sort(vec.begin(), vec.end());
     221             :   vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
     222         172 : }
     223             : 
     224             : inline
     225       19098 : bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val) {
     226       76277 :   for(auto p=line.begin(); p!=line.end(); ++p) {
     227       58388 :     if(key==*p) {
     228        1209 :       val=true;
     229             :       line.erase(p);
     230             :       return true;
     231             :     }
     232             :   }
     233             :   return false;
     234             : }
     235             : 
     236             : /// beware: this brings any number into a pbc that ranges from -0.5 to 0.5
     237             : inline
     238             : double Tools::pbc(double x) {
     239             : #ifdef __PLUMED_PBC_WHILE
     240             :   while (x>0.5) x-=1.0;
     241             :   while (x<-0.5) x+=1.0;
     242             :   return x;
     243             : #else
     244             :   if(std::numeric_limits<int>::round_style == std::round_toward_zero) {
     245             :     const double offset=100.0;
     246  1808821958 :     const double y=x+offset;
     247  1808821958 :     if(y>=0) return y-int(y+0.5);
     248        4577 :     else     return y-int(y-0.5);
     249             :   } else if(std::numeric_limits<int>::round_style == std::round_to_nearest) {
     250             :     return x-int(x);
     251             :   } else return x-floor(x+0.5);
     252             : #endif
     253             : }
     254             : 
     255             : template<typename T>
     256      285501 : void Tools::convert(T i,std::string & str) {
     257      571002 :   std::ostringstream ostr;
     258      191195 :   ostr<<i;
     259      571002 :   str=ostr.str();
     260      285501 : }
     261             : 
     262             : inline
     263             : double Tools::fastpow(double base, int exp)
     264             : {
     265    80001031 :   if(exp<0) {
     266           0 :     exp=-exp;
     267           0 :     base=1.0/base;
     268             :   }
     269             :   double result = 1.0;
     270   276034397 :   while (exp)
     271             :   {
     272   196033364 :     if (exp & 1)
     273   148360079 :       result *= base;
     274   196033364 :     exp >>= 1;
     275   196033364 :     base *= base;
     276             :   }
     277             : 
     278             :   return result;
     279             : }
     280             : 
     281             : template<typename T>
     282    13702163 : std::vector<T*> Tools::unique2raw(const std::vector<std::unique_ptr<T>> & x) {
     283    13702163 :   std::vector<T*> v(x.size());
     284   144453310 :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
     285    13702163 :   return v;
     286             : }
     287             : 
     288             : template<typename T>
     289             : std::vector<const T*> Tools::unique2raw(const std::vector<std::unique_ptr<const T>> & x) {
     290             :   std::vector<const T*> v(x.size());
     291             :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
     292             :   return v;
     293             : }
     294             : 
     295             : }
     296             : 
     297             : #endif
     298             : 

Generated by: LCOV version 1.14