LCOV - code coverage report
Current view: top level - tools - OFile.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 6 7 85.7 %
Date: 2020-11-18 11:20:57 Functions: 83 95 87.4 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2019 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_OFile_h
      23             : #define __PLUMED_tools_OFile_h
      24             : 
      25             : #include "FileBase.h"
      26             : #include <vector>
      27             : #include <sstream>
      28             : 
      29             : namespace PLMD {
      30             : 
      31             : class Value;
      32             : 
      33             : /**
      34             : \ingroup TOOLBOX
      35             : Class for output files
      36             : 
      37             : This class provides features similar to those in the standard C "FILE*" type,
      38             : but only for sequential output. See IFile for sequential input.
      39             : 
      40             : See the example here for a possible use:
      41             : \verbatim
      42             : #include "File.h"
      43             : 
      44             : int main(){
      45             :   PLMD::OFile pof;
      46             :   pof.open("ciao");
      47             :   pof.printf("%s\n","test1");
      48             :   pof.setLinePrefix("plumed: ");
      49             :   pof.printf("%s\n","test2");
      50             :   pof.setLinePrefix("");
      51             :   pof.addConstantField("x2").printField("x2",67.0);
      52             :   pof.printField("x1",10.0).printField("x3",20.12345678901234567890).printField();
      53             :   pof.printField("x1",10.0).printField("x3",-1e70*20.12345678901234567890).printField();
      54             :   pof.printField("x3",10.0).printField("x2",777.0).printField("x1",-1e70*20.12345678901234567890).printField();
      55             :   pof.printField("x3",67.0).printField("x1",18.0).printField();
      56             :   pof.close();
      57             :   return 0;
      58             : }
      59             : \endverbatim
      60             : 
      61             : This program is expected to produce a file "ciao" which reads
      62             : \verbatim
      63             : test1
      64             : plumed: test2
      65             : #! FIELDS x1 x3
      66             : #! SET x2                      67
      67             :                      10      20.12345678901234
      68             :                      10 -2.012345678901235e+71
      69             : #! FIELDS x1 x3
      70             : #! SET x2                     777
      71             :  -2.012345678901235e+71                     10
      72             :                      18                     67
      73             : \endverbatim
      74             : 
      75             : Notes
      76             : - "x2" is declared as "constant", which means that it is written using the "SET"
      77             : keyword. Thus, everytime it is modified, all the headers are repeated in the output file.
      78             : - printField() without arguments is used as a "newline".
      79             : - most methods return a reference to the OFile itself, to allow chaining many calls on the same line
      80             : (this is similar to << operator in std::ostream)
      81             : 
      82             : \section using-correctly-ofile Using correctly OFile in PLUMED
      83             : 
      84             : When a OFile object is used in PLUMED it can be convenient to link() it
      85             : to the Action object where it is defined, or to the PlumedMain object.
      86             : This will save in the OFile a pointer to the linked object and will
      87             : allow to have some extra information. E.g., if PLUMED is restarting,
      88             : files will be appended. Notice that one can enforce this behavior using
      89             : the enforceRestart() method before opening a file.
      90             : 
      91             : To have all files managed consistently, it is important to use OFile in the proper way.
      92             : This should allow multi-replica plumed, restart and backups to work in
      93             : the expected way. For this reason all the operations in OFile and IFile
      94             : are synchronizing all the processors of the group, so call to OFile functions
      95             : should always be performed by all processes; for this reason is also not usefull
      96             : to use Log for debugging because only master threads will actually write.
      97             : For debugging is better to use the standard stderr.
      98             : 
      99             : \verbatim
     100             : int main(){
     101             : // this is a growing file, containing a full history
     102             : // (frames are appended, as in traditional HILLS and COLVAR)
     103             :   OFile grw;
     104             : // this is a single-snapshopt file used e.g. for checkpointing
     105             : // (rewritten every time)
     106             :   OFile snp;
     107             : 
     108             : // open both files at the beginning
     109             : // (will go in \ref Action constructor)
     110             :   grw.open("growing");
     111             :   snp.open("snapshot");
     112             : 
     113             : // trajectory loop
     114             :   for(int i=0;i<nsteps;i++){
     115             : 
     116             : // files should be writen in the update() method of an \ref Action
     117             : 
     118             : // write on growing file
     119             :     grw<<"data at step "<<i<<\n";
     120             : 
     121             : // flushing
     122             : // it takes time, so do it only if data is critical
     123             : // better to leave this choice to the user with the FLUSH keyword
     124             : //    grw.flush();
     125             : 
     126             : // write on snapshot file
     127             :     snp.rewind();
     128             :     snp<<"snapshot at step "<<i<<"\n";
     129             :     snp.flush();
     130             : // the only difference is that snp is rewound
     131             : // notice that it should be rewound just before writing
     132             : // because rewind is going to move the file out of the way
     133             : // to have a safe copy of the file ("bck.last.filename")
     134             : // Also notice that snapshots should be flushed
     135             : // for this reason, it is better to write them only
     136             : // rarely to avoid excessive slow down
     137             : 
     138             :   }
     139             : 
     140             :   snp.close();
     141             :   grw.close();
     142             : }
     143             : 
     144             : \endverbatim
     145             : */
     146             : 
     147             : class OFile:
     148             :   public virtual FileBase {
     149             : /// Pointer to a linked OFile.
     150             : /// see link(OFile&)
     151             :   OFile* linked;
     152             : /// Internal buffer for printf
     153             :   char* buffer_string;
     154             : /// Internal buffer (generic use)
     155             :   char* buffer;
     156             : /// Internal buffer length
     157             :   int buflen;
     158             : /// This variables stores the actual buffer length
     159             :   int actual_buffer_length;
     160             : /// Class identifying a single field for fielded output
     161    42112237 :   class Field:
     162             :     public FieldBase {
     163             :   };
     164             : /// Low-level write
     165             :   size_t llwrite(const char*,size_t);
     166             : /// True if fields has changed.
     167             : /// This could be due to a change in the list of fields or a reset
     168             : /// of a nominally constant field
     169             :   bool fieldChanged;
     170             : /// Format for fields writing
     171             :   std::string fieldFmt;
     172             : /// All the previously defined variable fields
     173             :   std::vector<Field> previous_fields;
     174             : /// All the defined variable fields
     175             :   std::vector<Field> fields;
     176             : /// All the defined constant fields
     177             :   std::vector<Field> const_fields;
     178             : /// Prefix for line (e.g. "PLUMED: ")
     179             :   std::string linePrefix;
     180             : /// Temporary ostringstream for << output
     181             :   std::ostringstream oss;
     182             : /// The string used for backing up files
     183             :   std::string backstring;
     184             : /// Find field index given name
     185             :   unsigned findField(const std::string&name)const;
     186             : /// check if we are restarting
     187             :   bool checkRestart()const;
     188             : /// True if restart behavior should be forced
     189             :   bool enforceRestart_;
     190             : /// True if backup behavior (i.e. non restart) should be forced
     191             :   bool enforceBackup_;
     192             : public:
     193             : /// Constructor
     194             :   OFile();
     195             : /// Destructor
     196             :   ~OFile();
     197             : /// Allows overloading of link
     198             :   using FileBase::link;
     199             : /// Allows overloading of open
     200             :   using FileBase::open;
     201             : /// Allows linking this OFile to another one.
     202             : /// In this way, everything written to this OFile will be immediately
     203             : /// written on the linked OFile. Notice that a OFile should
     204             : /// be either opened explicitly, linked to a FILE or linked to a OFile
     205             :   OFile& link(OFile&);
     206             : /// Set the string name to be used for automatic backup
     207             :   void setBackupString( const std::string& );
     208             : /// Backup a file by giving it a different name
     209             :   void backupFile( const std::string& bstring, const std::string& fname );
     210             : /// This backs up all the files that would have been created with the
     211             : /// name str.  It is used in analysis when you are not restarting.  Analysis
     212             : /// output files at different times, which are names analysis.0.<filename>,
     213             : /// analysis.1.<filename> and <filename>, are backed up to bck.0.analysis.0.<filename>,
     214             : /// bck.0.analysis.1.<filename> and bck.0.<filename>
     215             :   void backupAllFiles( const std::string& str );
     216             : /// Opens the file using automatic append/backup
     217           0 :   OFile& open(const std::string&name);
     218             : /// Set the prefix for output.
     219             : /// Typically "PLUMED: ". Notice that lines with a prefix cannot
     220             : /// be parsed using fields in a IFile.
     221             :   OFile& setLinePrefix(const std::string&);
     222             : /// Set the format for writing double precision fields
     223             :   OFile& fmtField(const std::string&);
     224             : /// Reset the format for writing double precision fields to its default
     225             :   OFile& fmtField();
     226             : /// Set the value of a double precision field
     227             :   OFile& printField(const std::string&,double);
     228             : /// Set the value of a int field
     229             :   OFile& printField(const std::string&,int);
     230             : /// Set the value of a string field
     231             :   OFile& printField(const std::string&,const std::string&);
     232             : ///
     233             :   OFile& addConstantField(const std::string&);
     234             : /// Used to setup printing of values
     235             :   OFile& setupPrintValue( Value *val );
     236             : /// Print a value
     237             :   OFile& printField( Value* val, const double& v );
     238             :   /** Close a line.
     239             :   Typically used as
     240             :   \verbatim
     241             :     of.printField("a",a).printField("b",b).printField();
     242             :   \endverbatim
     243             :   */
     244             :   OFile& printField();
     245             :   /**
     246             :   Resets the list of fields.
     247             :   As it is only possible to add new constant fields (addConstantField()),
     248             :   this method can be used to clean the field list.
     249             :   */
     250             :   OFile& clearFields();
     251             : /// Formatted output with explicit format - a la printf
     252             :   int printf(const char*fmt,...);
     253             : /// Formatted output with << operator
     254             :   template <class T>
     255             :   friend OFile& operator<<(OFile&,const T &);
     256             : /// Rewind a file
     257             :   OFile&rewind();
     258             : /// Flush a file
     259             :   virtual FileBase&flush();
     260             : /// Enforce restart, also if the attached plumed object is not restarting.
     261             : /// Useful for tests
     262             :   OFile&enforceRestart();
     263             : /// Enforce backup, even if the attached plumed object is restarting.
     264             :   OFile&enforceBackup();
     265             : };
     266             : 
     267             : /// Write using << syntax
     268             : template <class T>
     269       67205 : OFile& operator<<(OFile&of,const T &t) {
     270       67205 :   of.oss<<t;
     271      134410 :   of.printf("%s",of.oss.str().c_str());
     272      134410 :   of.oss.str("");
     273       67205 :   return of;
     274             : }
     275             : 
     276             : 
     277             : }
     278             : 
     279             : #endif

Generated by: LCOV version 1.13