All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
IFile.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 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-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
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 #include "File.h"
23 #include "Exception.h"
24 #include "core/Action.h"
25 #include "core/PlumedMain.h"
26 #include "core/Value.h"
27 #include "Communicator.h"
28 #include "Tools.h"
29 #include <cstdarg>
30 #include <cstring>
31 
32 #include <iostream>
33 #include <string>
34 
35 namespace PLMD{
36 
37 size_t IFile::llread(char*ptr,size_t s){
38  plumed_assert(fp);
39  size_t r;
40  r=fread(ptr,1,s,fp);
41  if(feof(fp)) eof=true;
42  if(ferror(fp)) err=true;
43  return r;
44 }
45 
47  plumed_assert(!inMiddleOfField);
48  std::string line;
49  bool done=false;
50  while(!done){
51  getline(line);
52  if(!*this){return *this;}
53  std::vector<std::string> words=Tools::getWords(line);
54  if(words.size()>=2 && words[0]=="#!" && words[1]=="FIELDS"){
55  fields.clear();
56  for(unsigned i=2;i<words.size();i++){
57  Field field;
58  field.name=words[i];
59  fields.push_back(field);
60  }
61  } else if(words.size()==4 && words[0]=="#!" && words[1]=="SET"){
62  Field field;
63  field.name=words[2];
64  field.value=words[3];
65  field.constant=true;
66  fields.push_back(field);
67  } else {
68  unsigned nf=0;
69  for(unsigned i=0;i<fields.size();i++) if(!fields[i].constant) nf++;
70  Tools::trimComments(line);
71  words=Tools::getWords(line);
72  if( words.size()==nf ){
73  unsigned j=0;
74  for(unsigned i=0;i<fields.size();i++){
75  if(fields[i].constant) continue;
76  fields[i].value=words[j];
77  fields[i].read=false;
78  j++;
79  }
80  done=true;
81  } else if( !words.empty() ) {
82  plumed_merror("mismatch between number of fields in file and expected number");
83  }
84  }
85  }
86  inMiddleOfField=true;
87  return *this;
88 }
89 
90 IFile& IFile::open(const std::string&name){
91  FileBase::open(name,"r");
92  return *this;
93 }
94 
95 IFile& IFile::scanFieldList(std::vector<std::string>&s){
97  if(!*this) return *this;
98  s.clear();
99  for(unsigned i=0;i<fields.size();i++)
100  s.push_back(fields[i].name);
101  return *this;
102 }
103 
104 bool IFile::FieldExist(const std::string& s){
105  std::vector<std::string> slist;
106  scanFieldList(slist);
107  int mycount = (int) std::count(slist.begin(), slist.end(), s);
108  if(mycount>0) return true;
109  else return false;
110 }
111 
112 IFile& IFile::scanField(const std::string&name,std::string&str){
114  if(!*this) return *this;
115  unsigned i=findField(name);
116  str=fields[i].value;
117  fields[i].read=true;
118  return *this;
119 }
120 
121 IFile& IFile::scanField(const std::string&name,double &x){
122  std::string str;
123  scanField(name,str);
124  if(*this) Tools::convert(str,x);
125  return *this;
126 }
127 
128 IFile& IFile::scanField(const std::string&name,int &x){
129  std::string str;
130  scanField(name,str);
131  if(*this) Tools::convert(str,x);
132  return *this;
133 }
134 
136  double ff; scanField( val->getName(), ff );
137  val->set( ff );
138  if( FieldExist("min_" + val->getName() ) ){
139  std::string min, max;
140  scanField("min_" + val->getName(), min );
141  scanField("max_" + val->getName(), max );
142  val->setDomain( min, max );
143  } else {
144  val->setNotPeriodic();
145  }
146  return *this;
147 }
148 
150  if(!ignoreFields){
151  for(unsigned i=0;i<fields.size();i++){
152  plumed_massert(fields[i].read,"field "+fields[i].name+" was not read: all the fields need to be read otherwise you could miss important infos" );
153  }
154  }
155  inMiddleOfField=false;
156  return *this;
157 }
158 
160  inMiddleOfField(false),
161  ignoreFields(false)
162 {
163 }
164 
166  if(inMiddleOfField) std::cerr<<"WARNING: IFile closed in the middle of reading. seems strange!\n";
167 }
168 
169 IFile& IFile::getline(std::string &str){
170  char tmp;
171  str="";
172  fpos_t pos;
173  fgetpos(fp,&pos);
174  while(llread(&tmp,1)==1 && tmp && tmp!='\n' && !eof && !err){
175  str+=tmp;
176  }
177  if(err || eof || tmp!='\n'){
178  eof = true;
179  str="";
180  fsetpos(fp,&pos);
181  }
182  return *this;
183 }
184 
185 unsigned IFile::findField(const std::string&name)const{
186  unsigned i;
187  for(i=0;i<fields.size();i++) if(fields[i].name==name) break;
188  if(i>=fields.size()) plumed_merror(name);
189  return i;
190 }
191 
192 void IFile::reset(bool reset){
193  eof = reset;
194  err = reset;
195  if(!reset) clearerr(fp);
196  return;
197 }
198 
200  ignoreFields=true;
201 }
202 
203 }
bool FieldExist(const std::string &s)
Check if a field exist.
Definition: IFile.cpp:104
const std::string & getName() const
Get the name of the quantity.
Definition: Value.h:196
IFile()
Constructor.
Definition: IFile.cpp:159
IFile & getline(std::string &)
Get a full line as a string.
Definition: IFile.cpp:169
unsigned findField(const std::string &name) const
Find field index by name.
Definition: IFile.cpp:185
std::vector< Field > fields
All the defined fields.
Definition: IFile.h:53
A class for holding the value of a function together with its derivatives.
Definition: Value.h:46
bool inMiddleOfField
Flag set in the middle of a field reading.
Definition: IFile.h:55
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
void set(double)
Set the value of the function.
Definition: Value.h:174
void reset(bool)
Reset end of file.
Definition: IFile.cpp:192
void setNotPeriodic()
Set the function not periodic.
Definition: Value.cpp:87
IFile & open(const std::string &name)
Opens the file.
Definition: IFile.cpp:90
IFile & advanceField()
Advance to next field (= read one line)
Definition: IFile.cpp:46
static std::vector< std::string > getWords(const std::string &line, const char *sep=NULL, int *parlevel=NULL, const char *parenthesis="{")
Split the line in words using separators.
Definition: Tools.cpp:112
bool eof
Set to true when end of file is encountered.
Definition: FileBase.h:71
IFile & scanField()
Ends a field-formatted line.
Definition: IFile.cpp:149
FileBase & open(const std::string &name, const std::string &mode)
Opens the file (without auto-backup)
Definition: FileBase.cpp:99
bool ignoreFields
Set to true if you want to allow fields to be ignored in the read in file.
Definition: IFile.h:57
static void trimComments(std::string &s)
Remove trailing comments.
Definition: Tools.cpp:210
Class for input files.
Definition: IFile.h:40
~IFile()
Destructor.
Definition: IFile.cpp:165
FILE * fp
file pointer
Definition: FileBase.h:57
size_t llread(char *, size_t)
Low-level read.
Definition: IFile.cpp:37
bool err
Set to true when error is encountered.
Definition: FileBase.h:73
IFile & scanFieldList(std::vector< std::string > &)
Gets the list of all fields.
Definition: IFile.cpp:95
void setDomain(const std::string &, const std::string &)
Set the domain of the function.
Definition: Value.cpp:91
void allowIgnoredFields()
Allow some of the fields in the input to be ignored.
Definition: IFile.cpp:199