All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DumpAtoms.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 "core/ActionAtomistic.h"
23 #include "core/ActionPilot.h"
24 #include "core/ActionRegister.h"
25 #include "tools/Pbc.h"
26 #include "tools/File.h"
27 #include "core/PlumedMain.h"
28 #include "core/Atoms.h"
29 #include "tools/Units.h"
30 #include <cstdio>
31 #include "core/SetupMolInfo.h"
32 #include "core/ActionSet.h"
33 
34 using namespace std;
35 
36 namespace PLMD
37 {
38 namespace generic{
39 
40 //+PLUMEDOC ANALYSIS DUMPATOMS
41 /*
42 Dump selected atoms on a file.
43 
44 This command can be used to output the positions of a particular set of atoms.
45 The atoms required are ouput in a xyz or gro formatted file.
46 The type of file is automatically detected from the file extension, but can be also
47 enforced with TYPE.
48 Importantly, if your
49 input file contains actions that edit the atoms position (e.g. \ref WHOLEMOLECULES)
50 and the DUMPATOMS command appears after this instruction, then the edited
51 atom positions are output.
52 You can control the buffering of output using the \ref FLUSH keyword on a separate line.
53 
54 Units of the printed file can be controlled with the UNITS keyword. By default PLUMED units as
55 controlled in the \ref UNITS command are used, but one can override it e.g. with UNITS=A.
56 Notice that gro files can only contain coordinates in nm.
57 
58 \par Examples
59 
60 The following input instructs plumed to print out the positions of atoms
61 1-10 together with the position of the center of mass of atoms 11-20 every
62 10 steps to a file called file.xyz.
63 \verbatim
64 COM ATOMS=11-20 LABEL=c1
65 DUMPATOMS STRIDE=10 FILE=file.xyz ATOMS=1-10,c1
66 \endverbatim
67 (see also \ref COM)
68 
69 The following input is very similar but dumps a .gro (gromacs) file,
70 which also contains atom and residue names.
71 \verbatim
72 # this is required to have proper atom names:
73 MOLINFO STRUCTURE=reference.pdb
74 # if omitted, atoms will have "X" name...
75 
76 COM ATOMS=11-20 LABEL=c1
77 DUMPATOMS STRIDE=10 FILE=file.gro ATOMS=1-10,c1
78 # notice that last atom is a virtual one and will not have
79 # a correct name in the resulting gro file
80 \endverbatim
81 (see also \ref COM and \ref MOLINFO)
82 
83 
84 */
85 //+ENDPLUMEDOC
86 
87 class DumpAtoms:
88  public ActionAtomistic,
89  public ActionPilot
90 {
92  double lenunit;
93  std::vector<std::string> names;
94  std::vector<unsigned> residueNumbers;
95  std::vector<std::string> residueNames;
96  std::string type;
97 public:
98  DumpAtoms(const ActionOptions&);
99  ~DumpAtoms();
100  static void registerKeywords( Keywords& keys );
101  void calculate(){}
102  void apply(){}
103  void update();
104 };
105 
106 PLUMED_REGISTER_ACTION(DumpAtoms,"DUMPATOMS")
107 
108 void DumpAtoms::registerKeywords( Keywords& keys ){
109  Action::registerKeywords( keys );
110  ActionPilot::registerKeywords( keys );
111  ActionAtomistic::registerKeywords( keys );
112  keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
113  keys.add("atoms", "ATOMS", "the atom indices whose positions you would like to print out");
114  keys.add("compulsory", "FILE", "file on which to output coordinates. .gro extension is automatically detected");
115  keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
116  keys.add("optional", "TYPE","file type, either xyz or gro, can override an automatically detected file extension");
117 }
118 
119 DumpAtoms::DumpAtoms(const ActionOptions&ao):
120  Action(ao),
121  ActionAtomistic(ao),
122  ActionPilot(ao)
123 {
124  vector<AtomNumber> atoms;
125  string file;
126  parse("FILE",file);
127  if(file.length()==0) error("name out output file was not specified");
128  type=Tools::extension(file);
129  log<<" file name "<<file<<"\n";
130  if(type=="gro" || type=="xyz"){
131  log<<" file extension indicates a "<<type<<" file\n";
132  } else {
133  log<<" file extension not detected, assuming xyz\n";
134  type="xyz";
135  }
136  string ntype;
137  parse("TYPE",ntype);
138  if(ntype.length()>0){
139  if(ntype!="xyz" && ntype!="gro") error("TYPE should be either xyz or gro");
140  log<<" file type enforced to be "<<ntype<<"\n";
141  type=ntype;
142  }
143 
144  parseAtomList("ATOMS",atoms);
145 
146  std::string unitname; parse("UNITS",unitname);
147  if(unitname!="PLUMED"){
148  Units myunit; myunit.setLength(unitname);
149  if(myunit.getLength()!=1.0 && type=="gro") error("gro files should be in nm");
150  lenunit=plumed.getAtoms().getUnits().getLength()/myunit.getLength();
151  } else if(type=="gro") lenunit=plumed.getAtoms().getUnits().getLength();
152  else lenunit=1.0;
153 
154  checkRead();
155  of.link(*this);
156  of.open(file);
157  log.printf(" printing the following atoms in %s :", unitname.c_str() );
158  for(unsigned i=0;i<atoms.size();++i) log.printf(" %d",atoms[i].serial() );
159  log.printf("\n");
160  requestAtoms(atoms);
161  std::vector<SetupMolInfo*> moldat=plumed.getActionSet().select<SetupMolInfo*>();
162  if( moldat.size()==1 ){
163  log<<" MOLINFO DATA found, using proper atom names\n";
164  names.resize(atoms.size());
165  for(unsigned i=0;i<atoms.size();i++) names[i]=moldat[0]->getAtomName(atoms[i]);
166  residueNumbers.resize(atoms.size());
167  for(unsigned i=0;i<residueNumbers.size();++i) residueNumbers[i]=moldat[0]->getResidueNumber(atoms[i]);
168  residueNames.resize(atoms.size());
169  for(unsigned i=0;i<residueNames.size();++i) residueNames[i]=moldat[0]->getResidueName(atoms[i]);
170  }
171 }
172 
174  if(type=="xyz"){
175  of.printf("%d\n",getNumberOfAtoms());
176  const Tensor & t(getPbc().getBox());
177  if(getPbc().isOrthorombic()){
178  of.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
179  }else{
180  of.printf(" %f %f %f %f %f %f %f %f %f\n",
181  lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
182  lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
183  lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
184  );
185  }
186  for(unsigned i=0;i<getNumberOfAtoms();++i){
187  const char* defname="X";
188  const char* name=defname;
189  if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
190  of.printf("%s %f %f %f\n",name,lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
191  }
192  } else if(type=="gro"){
193  const Tensor & t(getPbc().getBox());
194  of.printf("Made with PLUMED t=%f\n",getTime()/plumed.getAtoms().getUnits().getTime());
195  of.printf("%d\n",getNumberOfAtoms());
196  for(unsigned i=0;i<getNumberOfAtoms();++i){
197  const char* defname="X";
198  const char* name=defname;
199  unsigned residueNumber=0;
200  if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
201  if(residueNumbers.size()>0) residueNumber=residueNumbers[i];
202  std::string resname="";
203  if(residueNames.size()>0) resname=residueNames[i];
204  of.printf("%5u%-5s%5s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f\n",residueNumber%100000,resname.c_str(),name,getAbsoluteIndex(i).serial()%100000,
205  lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2),0.0,0.0,0.0);
206  }
207  of.printf("%12.7f %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f\n",
208  lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2),
209  lenunit*t(0,1),lenunit*t(0,2),lenunit*t(1,0),
210  lenunit*t(1,2),lenunit*t(2,0),lenunit*t(2,1));
211  } else plumed_merror("unknown file type "+type);
212 }
213 
215 }
216 
217 
218 }
219 }
const Vector & getPosition(int) const
Get position of i-th atom.
std::vector< std::string > residueNames
Definition: DumpAtoms.cpp:95
Log & log
Reference to the log stream.
Definition: Action.h:93
This is used to create PLMD::Action objects that are run with some set frequency. ...
Definition: ActionPilot.h:39
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
unsigned serial() const
Returns the serial number.
Definition: AtomNumber.h:84
AtomNumber getAbsoluteIndex(int i) const
Get the absolute index of an atom.
void setLength(const std::string &)
Set lengh units from string.
Definition: Units.cpp:57
void error(const std::string &msg) const
Crash calculation and print documentation.
Definition: Action.cpp:195
void update()
Update.
Definition: DumpAtoms.cpp:173
void checkRead()
Check if Action was properly read.
Definition: Action.cpp:161
STL namespace.
void parseAtomList(const std::string &key, std::vector< AtomNumber > &t)
Parse a list of atoms without a numbered keyword.
const Pbc & getPbc() const
Get reference to Pbc.
void parse(const std::string &key, T &t)
Parse one keyword as generic type.
Definition: Action.h:273
This class holds the keywords and their documentation.
Definition: Keywords.h:36
const std::string name
Name of the directive in the plumed.dat file.
Definition: Action.h:64
Small utility class that contains information about units.
Definition: Units.h:41
This class is used to bring the relevant information to the Action constructor.
Definition: Action.h:41
Action used to create objects that access the positions of the atoms from the MD code.
OFile & link(OFile &)
Allows linking this OFile to another one.
Definition: OFile.cpp:71
double getTime() const
Return the present time.
Definition: Action.cpp:173
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Definition: OFile.cpp:82
void calculate()
Calculate an Action.
Definition: DumpAtoms.cpp:101
Base class for all the input Actions.
Definition: Action.h:60
static std::string extension(const std::string &)
Extract the extensions from a file name.
Definition: Tools.cpp:289
std::vector< std::string > names
Definition: DumpAtoms.cpp:93
Provides the keyword DUMPATOMS
Definition: DumpAtoms.cpp:87
std::vector< unsigned > residueNumbers
Definition: DumpAtoms.cpp:94
Class for output files.
Definition: OFile.h:84
const double & getLength() const
Get length units as double.
Definition: Units.h:95
void apply()
Apply an Action.
Definition: DumpAtoms.cpp:102
void requestAtoms(const std::vector< AtomNumber > &a)
Request an array of atoms.
Main plumed object.
Definition: Plumed.h:201
const Tensor & getBox() const
Get position of i-th atom.
unsigned getNumberOfAtoms() const
Get number of available atoms.
OFile & open(const std::string &name)
Opens the file using automatic append/backup.
Definition: OFile.cpp:264