From 77573a0e17ca5755611fde1e0c4c1455c89bb9a0 Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Fri, 23 Jan 2015 06:25:13 -0600
Subject: [PATCH] Per action restart

Allow individual action to set restart, using RESTART=YES or
RESTART=NO. By default, RESTART=AUTO, that means that global
restart settings are used.

Notice that this required to change the way OFile knows about
restart. Indeed, if the file is linked to an action,
it should use Action::getRestart instead of PlumedMain::getRestart.
---
 src/analysis/Analysis.cpp |  4 ++--
 src/bias/MetaD.cpp        |  2 +-
 src/core/Action.cpp       | 11 +++++++++++
 src/core/Action.h         | 10 ++++++++++
 src/core/ActionSetup.cpp  |  2 ++
 src/setup/Restart.cpp     | 29 ++++++++++++++++++++++++++---
 src/tools/OFile.cpp       |  6 ++++--
 7 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/src/analysis/Analysis.cpp b/src/analysis/Analysis.cpp
index 1d16fafe9..8ef44ac42 100644
--- a/src/analysis/Analysis.cpp
+++ b/src/analysis/Analysis.cpp
@@ -191,7 +191,7 @@ argument_names(getNumberOfArguments())
       // We need no restart file if we are just collecting data and analyzing all of it
       std::string filename = getName() + "_" + getLabel() + ".chkpnt"; 
       if( write_chq ) rfile.link(*this);
-      if( plumed.getRestart() ){
+      if( getRestart() ){
           if( single_run ) error("cannot restart histogram when using the USE_ALL_DATA option");
           if( !write_chq ) warning("restarting without writing a checkpoint file is somewhat strange");
           // Read in data from input file
@@ -241,7 +241,7 @@ void Analysis::parseOutputFile( const std::string& key, std::string& filename ){
   parse(key,filename);
   if(filename=="dont output") return;
 
-  if( !plumed.getRestart() ){
+  if( !getRestart() ){
       OFile ofile; ofile.link(*this);
       ofile.setBackupString("analysis");
       ofile.backupAllFiles(filename);
diff --git a/src/bias/MetaD.cpp b/src/bias/MetaD.cpp
index d24e4f9e8..a80bdfbbb 100644
--- a/src/bias/MetaD.cpp
+++ b/src/bias/MetaD.cpp
@@ -642,7 +642,7 @@ isFirstStep(true)
    ifilesnames.push_back(fname);
    if(ifile->FileExist(fname)){
     ifile->open(fname);
-    if(plumed.getRestart()){
+    if(getRestart()){
      log.printf("  Restarting from %s:",ifilesnames[i].c_str());                  
      readGaussians(ifiles[i]);                                                    
     }
diff --git a/src/core/Action.cpp b/src/core/Action.cpp
index 0181bca9a..c618c1721 100644
--- a/src/core/Action.cpp
+++ b/src/core/Action.cpp
@@ -49,12 +49,14 @@ keys(keys)
 void Action::registerKeywords( Keywords& keys ){
   plumed_assert( keys.size()==0 );
   keys.add( "hidden", "LABEL", "a label for the action so that its output can be referenced in the input to other actions.  Actions with scalar output are referenced using their label only.  Actions with vector output must have a separate label for every component.  Individual componets are then refered to using label.component" );
+  keys.add("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
 }
 
 Action::Action(const ActionOptions&ao):
   name(ao.line[0]),
   line(ao.line),
   active(false),
+  restart(ao.plumed.getRestart()),
   plumed(ao.plumed),
   log(plumed.getLog()),
   comm(plumed.comm),
@@ -72,6 +74,15 @@ Action::Action(const ActionOptions&ao):
   }
   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
   log.printf("  with label %s\n",label.c_str());
+
+  if ( keywords.exists("RESTART") ){
+    std::string srestart="AUTO";
+    parse("RESTART",srestart);
+    if(srestart=="YES") restart=true;
+    else if(srestart=="NO")  restart=false;
+    else if(srestart=="AUTO") {}
+    else error("RESTART should be either YES, NO, or AUTO");
+  }
 }
 
 Action::~Action(){
diff --git a/src/core/Action.h b/src/core/Action.h
index 4c5265616..336407926 100644
--- a/src/core/Action.h
+++ b/src/core/Action.h
@@ -84,6 +84,8 @@ private:
 /// Option that you might have enabled 
   std::set<std::string> options; 
 
+  bool restart;
+
 public:
 
 /// Reference to main plumed object
@@ -107,6 +109,9 @@ public:
 /// Return the timestep
   double getTimeStep()const;
 
+/// Return true if we are doing a restart
+  bool getRestart()const;
+
 /// Parse one keyword as generic type
   template<class T>
   void parse(const std::string&key,T&t);
@@ -381,6 +386,11 @@ bool Action::isOptionOn(const std::string &s)const{
   return options.count(s);
 }
 
+inline
+bool Action::getRestart()const{
+  return restart;
+}
+
 }
 #endif
 
diff --git a/src/core/ActionSetup.cpp b/src/core/ActionSetup.cpp
index deea21bd7..016da403d 100644
--- a/src/core/ActionSetup.cpp
+++ b/src/core/ActionSetup.cpp
@@ -39,6 +39,8 @@ ActionSetup::ActionSetup(const ActionOptions&ao):
 void ActionSetup::registerKeywords( Keywords& keys ){
   Action::registerKeywords(keys);
   keys.remove("LABEL");
+  keys.remove("RESTART");
+
 }
 
 }
diff --git a/src/setup/Restart.cpp b/src/setup/Restart.cpp
index 440a76e44..9a9ee6756 100644
--- a/src/setup/Restart.cpp
+++ b/src/setup/Restart.cpp
@@ -35,7 +35,18 @@ namespace setup{
 Activate restart.
 
 This is a Setup directive and, as such, should appear
-at the beginning of the input file.
+at the beginning of the input file. It influences the way
+PLUMED treat files open for writing (see also \ref Files).
+
+Notice that it is also possible to enable or disable restart on a per-action
+basis using the RESTART keyword on a single action. In this case,
+the keyword should be assigned a value. RESTART=AUTO means that global
+settings are used, RESTART=YES or RESTART=NO respectively enable
+and disable restart for that single action.
+
+\attention
+This directive can have also other side effects, e.g. on \ref METAD
+and on some analysis action.
 
 \par Examples
 
@@ -44,7 +55,9 @@ Using the following input:
 d: DISTANCE ATOMS=1,2
 PRINT ARG=d FILE=out
 \endverbatim
+(See also \ref DISTANCE and \ref PRINT).
 a new 'out' file will be created. If an old one is on the way, it will be automatically backed up.
+
 On the other hand, using the following input:
 \verbatim
 RESTART
@@ -54,8 +67,18 @@ PRINT ARG=d FILE=out
 the file 'out' will be appended.
 (See also \ref DISTANCE and \ref PRINT).
 
-\attention
-This directive can have also other side effects, e.g. on \ref METAD
+In the following case, file out1 will be backed up and file out2 will be concatenated
+\verbatim
+RESTART
+d1: DISTANCE ATOMS=1,2
+d2: DISTANCE ATOMS=1,2
+PRINT ARG=d1 FILE=out1 RESTART=NO
+PRINT ARG=d2 FILE=out2
+\endverbatim
+(See also \ref DISTANCE and \ref PRINT).
+
+
+
 
 */
 //+ENDPLUMEDOC
diff --git a/src/tools/OFile.cpp b/src/tools/OFile.cpp
index 25312b5d1..3a4214592 100644
--- a/src/tools/OFile.cpp
+++ b/src/tools/OFile.cpp
@@ -234,7 +234,7 @@ void OFile::setBackupString( const std::string& str ){
 }
 
 void OFile::backupAllFiles( const std::string& str ){
-  plumed_assert( backstring!="bck" && plumed && !plumed->getRestart() );
+  plumed_assert( backstring!="bck" && !checkRestart());
   size_t found=str.find_last_of("/\\");
   std::string filename = appendSuffix(str,plumed->getSuffix());
   std::string directory=filename.substr(0,found+1);
@@ -362,7 +362,9 @@ FileBase& OFile::flush(){
 }
 
 bool OFile::checkRestart()const{
-  if(enforceRestart_ || (plumed && plumed->getRestart() ) ) return true;
+  if(enforceRestart_) return true;
+  else if(action) return action->getRestart();
+  else if(plumed) return plumed->getRestart();
   else return false;
 }
 
-- 
GitLab