LOOS  v2.3.2
amber_netcdf.hpp
1 // (c) 2012 Tod D. Romo, Grossfield Lab, URMC
2 
3 #if !defined(LOOS_AMBER_NETCDF_HPP)
4 #define LOOS_AMBER_NETCDF_HPP
5 
6 
7 #include <istream>
8 #include <string>
9 #include <netcdf.h>
10 
11 #include <loos_defs.hpp>
12 #include <Coord.hpp>
13 #include <Trajectory.hpp>
14 #include <exceptions.hpp>
15 
16 #include <amber_traj.hpp>
17 
18 namespace loos {
19 
20 
22  bool isFileNetCDF(const std::string& fname);
23 
24 
25 
26 
27 
28  namespace {
29 
30 
31  // These classes handle the template specialization for
32  // determining which nc_get_vara function to call depending on the
33  // desired output type. NetCDF will handle any necessary
34  // conversion from the variable's native format.
35  template<typename T>
36  class VarTypeDecider {
37 
38  // This is private to keep arbitrary types from compiling
39  static int read(const int id, const int var, const size_t* st, const size_t *co, T* ip) { return(0); }
40  };
41 
42 
43 
44  // The following are the supported types (based on what GCoord
45  // typically holds...
46 
47  template<> class VarTypeDecider<float> {
48  public:
49  static int read(const int id, const int var, const size_t* st, const size_t* co, float* ip) {
50  return(nc_get_vara_float(id, var, st, co, ip));
51  }
52  };
53 
54  template<> class VarTypeDecider<double> {
55  public:
56  static int read(const int id, const int var, const size_t* st, const size_t* co, double* ip) {
57  return(nc_get_vara_double(id, var, st, co, ip));
58  }
59  };
60 
61 
62  }
63 
64 
65 
67  class AmberNetcdf : public Trajectory {
68  public:
69 
70 
71  // Note: we don't call the base class constructor because we need
72  // to keep it from trying to use an istream (since the C netcdf API
73  // doesn't support this)
74 
75  explicit AmberNetcdf(const std::string& s, const uint na)
76  : Trajectory(s),
77  _coord_data(new GCoord::element_type[na*3]),
78  _box_data(new GCoord::element_type[3]),
79  _periodic(false),
80  _timestep(1e-12),
81  _current_frame(0)
82  {
83  cached_first = false;
84  init(s.c_str(), na);
85  }
86 
87 
88  ~AmberNetcdf() {
89  // ignore the return code since throwing in destructors is bad...
90  nc_close(_ncid);
91 
92  delete[] _coord_data;
93  delete[] _box_data;
94  }
95 
96  std::string description() const { return("Amber trajectory (netCDF)"); }
97  static pTraj create(const std::string& fname, const AtomicGroup& model) {
98  if (isFileNetCDF(fname))
99  return(pTraj(new AmberNetcdf(fname, model.size())));
100 
101  return(pTraj(new AmberTraj(fname, model.size())));
102  }
103 
104  uint natoms() const { return(_natoms); }
105  uint nframes() const { return(_nframes); }
106  float timestep() const { return(_timestep); }
107 
108  bool hasPeriodicBox() const { return(_periodic); }
109  GCoord periodicBox() const { return(GCoord(_box_data[0], _box_data[1], _box_data[2])); }
110 
111  std::vector<GCoord> coords() {
112  std::vector<GCoord> res;
113  for (uint i=0; i<_natoms; i += 3)
114  res.push_back(GCoord(_coord_data[i], _coord_data[i+1], _coord_data[i+2]));
115  return(res);
116  }
117 
118  private:
119  void init(const char* name, const uint natoms);
120  void readGlobalAttributes();
121  std::string readGlobalAttribute(const std::string& name);
122  void readRawFrame(const uint frameno);
123 
124  void updateGroupCoordsImpl(AtomicGroup& g);
125  bool parseFrame();
126  void seekNextFrameImpl();
127  void seekFrameImpl(const uint frame);
128  void rewindImpl();
129 
130 
131  private:
132  GCoord::element_type* _coord_data;
133  GCoord::element_type* _box_data;
134  bool _periodic;
135  float _timestep;
136  uint _current_frame;
137  int _ncid;
138  size_t _nframes;
139  size_t _natoms;
140  int _coord_id;
141  size_t _coord_size;
142  int _cell_lengths_id;
143  std::string _title, _application, _program, _programVersion, _conventions, _conventionVersion;
144  };
145 
146 
147 }
148 
149 
150 
151 #endif
Class for reading amber coordinate trajectories.
Definition: amber_traj.hpp:48
uint natoms() const
of atoms per frame
float timestep() const
Timestep per frame.
uint nframes() const
Number of frames in the trajectory.
GCoord periodicBox() const
Returns the periodic box for the current frame/trajectory.
Class for reading Amber Trajectories in NetCDF format.
bool hasPeriodicBox() const
bool isFileNetCDF(const std::string &fname)
Returns true if the file is a NetCDF file.
Definition: amber_netcdf.cpp:9
std::vector< GCoord > coords()
Returns the current frames coordinates as a vector of GCoords.
Class for handling groups of Atoms (pAtoms, actually)
Definition: AtomicGroup.hpp:87
Namespace for most things not already encapsulated within a class.
std::string description() const
Return a string describing trajectory format.
Base-class for polymorphic trajectories.
Definition: Trajectory.hpp:64