diff --git a/doc/cpptraj.lyx b/doc/cpptraj.lyx
index 84115fe26e..df89c9d7e5 100644
--- a/doc/cpptraj.lyx
+++ b/doc/cpptraj.lyx
@@ -4602,13 +4602,25 @@ Read
\end_layout
\begin_layout LyX-Code
-[index
] [read2d] [vector] [mat3x3]
+[ read1d [index ] [onlycols ] ]
+\end_layout
+
+\begin_layout LyX-Code
+[read2d] [vector] [mat3x3]
\begin_inset Separator latexpar
\end_inset
\end_layout
+\begin_layout LyX-Code
+[ read3d [dims ,,] [origin ,,]
+\end_layout
+
+\begin_layout LyX-Code
+ [delta ,,dz>] [prec {dbl|flt}] [bin {center|corner}]
+\end_layout
+
\begin_deeper
\begin_layout Description
index
@@ -4622,6 +4634,24 @@ index
read1d Read data as 1D data sets (default).
\end_layout
+\begin_deeper
+\begin_layout Description
+index
+\begin_inset space ~
+\end_inset
+
+ Use column (starting from 1) as index column (1D data only).
+\end_layout
+
+\begin_layout Description
+onlycols
+\begin_inset space ~
+\end_inset
+
+ Only read columns in range.
+\end_layout
+
+\end_deeper
\begin_layout Description
read2d Read data as 2D square matrix.
\end_layout
@@ -4641,6 +4671,53 @@ mat3x3 Read data as 3x3 matrix.
M(3,2) M(3,3).
\end_layout
+\begin_layout Description
+read3d Read data as 3D grid.
+ If no dimension data in file must also speify 'dims'.
+\end_layout
+
+\begin_deeper
+\begin_layout Description
+dims
+\begin_inset space ~
+\end_inset
+
+,, Grid dimensions.
+\end_layout
+
+\begin_layout Description
+origin
+\begin_inset space ~
+\end_inset
+
+,, Grid origins (default 0,0,0).
+\end_layout
+
+\begin_layout Description
+delta
+\begin_inset space ~
+\end_inset
+
+,,dz> Grid spacings (default 1,1,1).
+\end_layout
+
+\begin_layout Description
+prec
+\begin_inset space ~
+\end_inset
+
+{dbl|flt} Grid precision, double or float (default float).
+\end_layout
+
+\begin_layout Description
+bin
+\begin_inset space ~
+\end_inset
+
+{center|corner} Coords specify bin centers or corners (default corners).
+\end_layout
+
+\end_deeper
\end_deeper
\begin_layout Standard
By default, standard data files are assumed to contain 1D data in columns.
@@ -4736,11 +4813,11 @@ Write
\end_layout
\begin_layout LyX-Code
-[nolabels] [usemap] [pm3d] [nopm3d] [jpeg] [noheader]
+[nolabels] [usemap] [pm3d] [nopm3d] [title ]
\end_layout
\begin_layout LyX-Code
-[{xlabels|ylabels|zlabels} ]
+[jpeg] [noheader] [{xlabels|ylabels|zlabels} ]
\begin_inset Separator latexpar
\end_inset
@@ -4768,6 +4845,14 @@ nopm3d Turn off pm3d
jpeg Plot will write to a JPEG file when used with gnuplot.
\end_layout
+\begin_layout Description
+title
+\begin_inset space ~
+\end_inset
+
+ Set plot title (default is file name).
+\end_layout
+
\begin_layout Description
binary Plot will be written in binary format.
\end_layout
@@ -6188,7 +6273,7 @@ The following general commands are available:
\begin_layout Standard
\align center
\begin_inset Tabular
-
+
@@ -6774,6 +6859,26 @@ sortensembledata
Sort data sets using replica information (currently constant pH only).
\end_layout
+\end_inset
+
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+usediskcache
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+Turn caching of data sets to disk on or off.
+\end_layout
+
\end_inset
|
@@ -9221,6 +9326,30 @@ Sort unsorted data sets.
Currently only works for constant pH REMD data.
\end_layout
+\begin_layout Subsection
+usediskcache
+\end_layout
+
+\begin_layout LyX-Code
+usediskcache {on|off}
+\end_layout
+
+\begin_layout Standard
+If on, CPPTRAJ will attempt to cache data sets to disk if possible.
+ This currently only works for integer data sets (e.g.
+
+\series bold
+\emph on
+hbond
+\series default
+\emph default
+
+\series bold
+series
+\series default
+ data sets, etc).
+\end_layout
+
\begin_layout Subsection
write | writedata
\begin_inset CommandInset label
diff --git a/src/Action_ClusterDihedral.cpp b/src/Action_ClusterDihedral.cpp
index 3bb2c52e44..e8bd203b74 100644
--- a/src/Action_ClusterDihedral.cpp
+++ b/src/Action_ClusterDihedral.cpp
@@ -314,7 +314,7 @@ void Action_ClusterDihedral::Print() {
num = 0;
for (std::vector::const_iterator cnum = framecluster.begin();
cnum != framecluster.end(); ++cnum)
- (*iCVT)[ num++ ] = (int)*cnum + 1;
+ iCVT->SetElement( num++, (int)*cnum + 1 );
}
// Print cluster for each frame
diff --git a/src/Action_CreateCrd.cpp b/src/Action_CreateCrd.cpp
index 34944632c8..0e4a606d56 100644
--- a/src/Action_CreateCrd.cpp
+++ b/src/Action_CreateCrd.cpp
@@ -72,7 +72,7 @@ Action::RetType Action_CreateCrd::Setup(ActionSetup& setup) {
// Estimate memory usage
mprintf("\tEstimated memory usage (%i frames): %s\n",
setup.Nframes(),
- ByteString(coords_->SizeInBytes(setup.Nframes()), BYTE_DECIMAL).c_str());
+ ByteString(coords_->EstSizeInBytes(setup.Nframes()), BYTE_DECIMAL).c_str());
}
// If # atoms in currentParm does not match coords, warn user.
if (setup.Top().Natom() != coords_->Top().Natom()) {
diff --git a/src/Action_GIST.cpp b/src/Action_GIST.cpp
index d8c38814f0..3ade5c98ee 100644
--- a/src/Action_GIST.cpp
+++ b/src/Action_GIST.cpp
@@ -279,7 +279,7 @@ Action::RetType Action_GIST::Init(ArgList& actionArgs, ActionInit& init, int deb
mprintf("\tComputing and printing water-water Eij matrix, output to '%s'\n",
eijfile_->Filename().full());
mprintf("\tWater-water Eij matrix size is %s\n",
- ByteString(ww_Eij_->SizeInBytes(), BYTE_DECIMAL).c_str());
+ ByteString(ww_Eij_->MemUsageInBytes(), BYTE_DECIMAL).c_str());
} else
mprintf("\tSkipping water-water Eij matrix.\n");
mprintf("\tWater reference density: %6.4f molecules/Ang^3\n", BULK_DENS_);
diff --git a/src/Action_HydrogenBond.cpp b/src/Action_HydrogenBond.cpp
index c6e446433b..ba1acbc882 100644
--- a/src/Action_HydrogenBond.cpp
+++ b/src/Action_HydrogenBond.cpp
@@ -1086,11 +1086,13 @@ int Action_HydrogenBond::SyncAction() {
if (series_) {
for (int in = 0; in != n_total_on_rank; in++) {
DataSet_integer* ds = Svals[in];
- ds->Resize( Nframes_ );
- int* d_beg = ds->Ptr() + rank_offsets[ rank ];
- //mprintf("\tResizing hbond series data to %i, starting frame %i, # frames %i\n",
- // Nframes_, rank_offsets[rank], rank_frames[rank]);
- trajComm_.Recv( d_beg, rank_frames[ rank ], MPI_INT, rank, 1304 + in );
+ //ds->Resize( Nframes_ );
+ //int* d_beg = ds->Ptr() + rank_offsets[ rank ];
+ //rprintf("Resizing hbond series data to %i, starting frame %i, # frames %i from rank %i (%i)\n",
+ // Nframes_, rank_offsets[rank], rank_frames[rank], rank, 1304 + in);
+ ds->Recv(Nframes_, rank_offsets[ rank ], rank_frames[ rank ],
+ rank, 1304 + in, trajComm_);
+ //trajComm_.Recv( d_beg, rank_frames[ rank ], MPI_INT, rank, 1304 + in );
ds->SetNeedsSync( false );
}
}
@@ -1134,11 +1136,15 @@ int Action_HydrogenBond::SyncAction() {
if (series_) {
int in = 0; // For tag
for (UUmapType::const_iterator hb = UU_Map_.begin(); hb != UU_Map_.end(); ++hb, in++) {
- trajComm_.Send( hb->second.Data()->Ptr(), hb->second.Data()->Size(), MPI_INT, 0, 1304 + in );
+ //rprintf("Sending %zu frames to master (%i).\n", hb->second.Data()->Size(), 1304+in);
+ hb->second.Data()->Send( 0, 1304 + in, trajComm_ );
+ //trajComm_.Send( hb->second.Data()->Ptr(), hb->second.Data()->Size(), MPI_INT, 0, 1304 + in );
hb->second.Data()->SetNeedsSync( false );
}
for (UVmapType::const_iterator hb = UV_Map_.begin(); hb != UV_Map_.end(); ++hb, in++) {
- trajComm_.Send( hb->second.Data()->Ptr(), hb->second.Data()->Size(), MPI_INT, 0, 1304 + in );
+ //rprintf("Sending %zu frames to master (%i).\n", hb->second.Data()->Size(), 1304+in);
+ hb->second.Data()->Send( 0, 1304 + in, trajComm_ );
+ //trajComm_.Send( hb->second.Data()->Ptr(), hb->second.Data()->Size(), MPI_INT, 0, 1304 + in );
hb->second.Data()->SetNeedsSync( false );
}
}
diff --git a/src/Analysis_Clustering.cpp b/src/Analysis_Clustering.cpp
index 98a4db46c5..0512d0165e 100644
--- a/src/Analysis_Clustering.cpp
+++ b/src/Analysis_Clustering.cpp
@@ -745,11 +745,10 @@ Analysis::RetType Analysis_Clustering::Analyze() {
// Change cluster num v time to grace-compatible colors if specified.
if (grace_color_) {
DataSet_integer& cnum_temp = static_cast( *cnumvtime_ );
- for (DataSet_integer::iterator ival = cnum_temp.begin();
- ival != cnum_temp.end(); ++ival)
+ for (unsigned int idx = 0; idx != cnum_temp.Size(); idx++)
{
- *ival += 1;
- if (*ival > 15) *ival = 15;
+ cnum_temp.AddVal(idx, 1);
+ if (cnum_temp[idx] > 15) cnum_temp.SetElement(idx, 15);
}
}
// Coordinate output.
@@ -849,10 +848,9 @@ void Analysis_Clustering::CreateCnumvtime( ClusterList const& CList, unsigned in
// access specific integer dataset functions for resizing and []
// operator. Should this eventually be generic to all atomic DataSets?
DataSet_integer& cnum_temp = static_cast( *cnumvtime_ );
- cnum_temp.Resize( maxFrames );
// Make all clusters start at -1. This way cluster algorithms that
// have noise points (i.e. no cluster assigned) will be distinguished.
- std::fill(cnum_temp.begin(), cnum_temp.end(), -1);
+ cnum_temp.Assign( maxFrames, -1 );
for (ClusterList::cluster_iterator C = CList.begincluster();
C != CList.endcluster(); C++)
@@ -864,7 +862,7 @@ void Analysis_Clustering::CreateCnumvtime( ClusterList const& CList, unsigned in
frame != (*C).endframe(); frame++)
{
//mprinterr("%i,",*frame);
- cnum_temp[ *frame ] = cnum;
+ cnum_temp.SetElement(*frame, cnum);
}
//mprinterr("\n");
//break;
@@ -945,7 +943,7 @@ void Analysis_Clustering::ClusterLifetimes( ClusterList const& CList, unsigned i
int cluster_num = cnum_temp[frame];
// Noise points are -1
if (cluster_num > -1)
- (*DSL[ cluster_num ])[ frame ] = 1;
+ DSL[ cluster_num ]->SetElement( frame, 1 );
}
}
diff --git a/src/Analysis_RemLog.cpp b/src/Analysis_RemLog.cpp
index 7ad0d60fe4..194a7dfb39 100644
--- a/src/Analysis_RemLog.cpp
+++ b/src/Analysis_RemLog.cpp
@@ -195,7 +195,7 @@ Analysis::RetType Analysis_RemLog::Analyze() {
// Variables for calculating replica lifetimes
Analysis_Lifetime Lifetime;
Array1D dsLifetime;
- std::vector< std::vector > series; // 2D - repidx, crdidx
+ std::vector< std::vector > series; // 2D - repidx, crdidx
if (calculateLifetimes_) {
mprintf("\tData size used for lifetime analysis= %zu bytes.\n",
remlog_->Size() * remlog_->Size() * remlog_->NumExchange() * sizeof(int));
@@ -252,13 +252,13 @@ Analysis::RetType Analysis_RemLog::Analyze() {
}
if (mode_ == CRDIDX) {
DataSet_integer& ds = static_cast( *(outputDsets_[repidx]) );
- ds[frame] = frm.CoordsIdx();
+ ds.SetElement(frame, frm.CoordsIdx());
} else if (mode_ == REPIDX) {
DataSet_integer& ds = static_cast( *(outputDsets_[crdidx]) );
- ds[frame] = frm.ReplicaIdx();
+ ds.SetElement(frame, frm.ReplicaIdx());
}
if (calculateLifetimes_)
- series[repidx][crdidx][frame] = 1;
+ series[repidx][crdidx].SetElement(frame, 1);
if (calculateStats_) {
TripStats& trip = static_cast( DimTrips[dim] );
// Fraction spent at each replica
diff --git a/src/Analysis_RemLog.h b/src/Analysis_RemLog.h
index 32ac2a8739..60290415f1 100644
--- a/src/Analysis_RemLog.h
+++ b/src/Analysis_RemLog.h
@@ -2,7 +2,7 @@
#define INC_ANALYSIS_REMLOG_H
#include "Analysis.h"
#include "DataSet_RemLog.h"
-#include "DataSet_integer.h"
+#include "DataSet_integer_mem.h"
class Analysis_RemLog : public Analysis {
public:
Analysis_RemLog();
@@ -14,7 +14,7 @@ class Analysis_RemLog : public Analysis {
enum ModeType { NONE = 0, CRDIDX, REPIDX };
typedef std::vector Iarray;
- typedef std::vector DSI_array;
+ typedef std::vector DSI_array;
/// Track exchange stats for each dimension.
class RepStats {
public:
diff --git a/src/AtomType.h b/src/AtomType.h
index 04a2273081..e231c82cef 100644
--- a/src/AtomType.h
+++ b/src/AtomType.h
@@ -20,6 +20,8 @@ class AtomType {
bool operator==(AtomType const&) const;
/// Combine LJ params with this and another type using Lorentz-Berthelot rules
NonbondType Combine_LB(AtomType const&) const;
+ /// \return data size
+ static size_t DataSize() { return (3*sizeof(double)) + sizeof(int); }
private:
double radius_; ///< VDW radius
double depth_; ///< LJ well-depth
diff --git a/src/AtomTypeArray.h b/src/AtomTypeArray.h
index 1ca3d6ddec..4a77838486 100644
--- a/src/AtomTypeArray.h
+++ b/src/AtomTypeArray.h
@@ -23,6 +23,13 @@ class AtomTypeArray {
typedef Tmap::const_iterator const_iterator;
const_iterator begin() const { return nameToIdx_.begin(); }
const_iterator end() const { return nameToIdx_.end(); }
+
+ size_t DataSize() const { return (types_.size() * AtomType::DataSize()) +
+ (nameToIdx_.size() * NameType::DataSize()) +
+ (nameToIdx_.size() * sizeof(int)) +
+ sizeof(Tmap) +
+ sizeof(int);
+ }
private:
typedef std::pair Tpair;
diff --git a/src/Command.cpp b/src/Command.cpp
index a7740ca35a..df477b374d 100644
--- a/src/Command.cpp
+++ b/src/Command.cpp
@@ -228,6 +228,7 @@ void Command::Init() {
Command::AddCmd( new Exec_SequenceAlign(), Cmd::EXE, 1, "sequencealign" );
Command::AddCmd( new Exec_SortEnsembleData(),Cmd::EXE, 1, "sortensembledata" );
Command::AddCmd( new Exec_WriteDataFile(), Cmd::EXE, 2, "write", "writedata" );
+ Command::AddCmd( new Exec_UseDiskCache(), Cmd::EXE, 1, "usediskcache" );
Command::AddCmd( new Exec_ViewRst(), Cmd::EXE, 1, "viewrst" ); // HIDDEN
# ifdef MPI
Command::AddCmd( new Exec_ForceParaEnsemble(), Cmd::EXE, 1, "forceparaensemble" );
diff --git a/src/ComplexArray.h b/src/ComplexArray.h
index 0dd453cbba..e5d898e655 100644
--- a/src/ComplexArray.h
+++ b/src/ComplexArray.h
@@ -33,6 +33,8 @@ class ComplexArray {
typedef ArrayIterator iterator;
const iterator begin() const { return data_; }
const iterator end() const { return data_ + ndata_; }
+
+ size_t DataSize() const { return ndata_*sizeof(double) + 2*sizeof(int) + sizeof(double*); }
private:
double* data_;
int ndata_; ///< Actual size of data
diff --git a/src/Cph.h b/src/Cph.h
index 839e574b43..f14f993b57 100644
--- a/src/Cph.h
+++ b/src/Cph.h
@@ -31,6 +31,11 @@ class CpRes {
static const int FULL_RECORD;
/// Indicate partial record written.
static const int PARTIAL_RECORD;
+ /// \return data size
+ size_t DataSize() const { return NameType::DataSize() +
+ sizeof(int) +
+ (protcnts_.size() * sizeof(int)) +
+ (protonated_.size() * sizeof(int)); }
private:
NameType resname_; ///< Residue name.
int resid_; ///< Residue number.
@@ -46,6 +51,7 @@ class CpTime {
int MonteCarloStepSize() const { return mc_stepsize_; }
float InitialTime() const { return t0_; }
float TimeStep() const { return dt_; }
+ static size_t DataSize() { return 2*sizeof(float) + sizeof(int); }
private:
float t0_; ///< Initial time
float dt_; ///< Time step
diff --git a/src/DataIO_Gnuplot.cpp b/src/DataIO_Gnuplot.cpp
index 6826ed5182..1f6f7b0caa 100644
--- a/src/DataIO_Gnuplot.cpp
+++ b/src/DataIO_Gnuplot.cpp
@@ -215,23 +215,24 @@ DataIO_Gnuplot::LabelArray DataIO_Gnuplot::LabelArg( std::string const& labelarg
}
void DataIO_Gnuplot::WriteHelp() {
- mprintf("\tnolabels: Do not print axis labels.\n"
- "\tusemap: pm3d output with 1 extra empty row/col (may improve look).\n"
- "\tpm3d: Normal pm3d map output.\n"
- "\tnopm3d: Turn off pm3d\n"
- "\tjpeg: Plot will write to a JPEG file when used with gnuplot.\n"
- "\ttitle: Plot title. Default is file name.\n"
+ mprintf("\tnolabels : Do not print axis labels.\n"
+ "\tusemap : pm3d output with 1 extra empty row/col (may improve look).\n"
+ "\tpm3d : Normal pm3d map output.\n"
+ "\tnopm3d : Turn off pm3d\n"
+ "\tjpeg : Plot will write to a JPEG file when used with gnuplot.\n"
+ "\ttitle : Plot title. Default is file name.\n"
// "\tbinary: Use binary output\n"
- "\tnoheader: Do not format plot; data output only.\n"
- "\tpalette : Change gnuplot pm3d palette to :\n"
+ "\tnoheader : Do not format plot; data output only.\n"
+ "\ttitle : Set plot title (default file base name).\n"
+ "\tpalette : Change gnuplot pm3d palette to :\n"
"\t 'rgb' - Red, yellow, green, cyan, blue, magenta, red.\n"
"\t 'kbvyw' - Black, blue, violet, yellow, white.\n"
"\t 'bgyr' - Blue, green, yellow, red.\n"
"\t 'gray' - Grayscale.\n"
- "\txlabels : Set x axis labels with comma-separated list, e.g.\n"
+ "\txlabels : Set x axis labels with comma-separated list, e.g.\n"
"\t 'xlabels X1,X2,X3'\n"
- "\tylabels : Set y axis labels.\n"
- "\tzlabels : Set z axis labels.\n");
+ "\tylabels : Set y axis labels.\n"
+ "\tzlabels : Set z axis labels.\n");
}
// DataIO_Gnuplot::processWriteArgs()
diff --git a/src/DataIO_Std.cpp b/src/DataIO_Std.cpp
index 72a61ccd21..76bd13234e 100644
--- a/src/DataIO_Std.cpp
+++ b/src/DataIO_Std.cpp
@@ -9,6 +9,7 @@
#include "StringRoutines.h" // SetStringFormatString
#include "BufferedLine.h"
#include "TextFormat.h"
+#include "DataSet_integer.h"
#include "DataSet_double.h" // For reading TODO remove dependency?
#include "DataSet_string.h" // For reading TODO remove dependency?
#include "DataSet_Vector.h" // For reading TODO remove dependency?
@@ -47,6 +48,8 @@ static void PrintColumnError(int idx) {
void DataIO_Std::ReadHelp() {
mprintf("\tread1d: Read data as 1D data sets (default).\n"
+ "\t\tindex : (1D) Use column # (starting from 1) as index (X) column.\n"
+ "\t\tonlycols : Only read columns in range.\n"
"\tread2d: Read data as 2D square matrix.\n"
"\tread3d: Read data as 3D grid. If no dimension data in file must also\n"
"\t specify 'dims'; can also specify 'origin' and 'delta'.\n"
@@ -56,8 +59,7 @@ void DataIO_Std::ReadHelp() {
"\t\tprec {dbl|flt*} : Grid precision; double or float (default float).\n"
"\t\tbin {center|corner*} : Coords specify bin centers or corners (default corners).\n"
"\tvector: Read data as vector: VX VY VZ [OX OY OZ]\n"
- "\tmat3x3: Read data as 3x3 matrices: M(1,1) M(1,2) ... M(3,2) M(3,3)\n"
- "\tindex : (1D) Use column # (starting from 1) as index (X) column.\n");
+ "\tmat3x3: Read data as 3x3 matrices: M(1,1) M(1,2) ... M(3,2) M(3,3)\n");
}
@@ -96,6 +98,11 @@ int DataIO_Std::processReadArgs(ArgList& argIn) {
return 1;
}
if (indexcol_ > 0) --indexcol_;
+ std::string ocarg = argIn.GetStringKey("onlycols");
+ if (!ocarg.empty()) {
+ onlycols_.SetRange( ocarg );
+ onlycols_.ShiftBy( -1 );
+ }
// Options for 3d
if (mode_ == READ3D) {
if (Get3Double(argIn.GetStringKey("origin"), origin_, originSpecified_)) return 1;
@@ -220,35 +227,56 @@ int DataIO_Std::Read_1D(std::string const& fname,
labels.ClearList();
hasLabels = false;
}
- if (indexcol_ != -1 && indexcol_ >= ntoken) {
- mprinterr("Error: Specified index column %i is out of range (%i columns).\n",
- indexcol_+1, ntoken);
- return 1;
+ // Index column checks
+ if (indexcol_ != -1 ) {
+ if (indexcol_ >= ntoken) {
+ mprinterr("Error: Specified index column %i is out of range (%i columns).\n",
+ indexcol_+1, ntoken);
+ return 1;
+ }
+ if (!onlycols_.Empty() && !onlycols_.InRange(indexcol_)) {
+ mprinterr("Error: Index column %i specified, but not in given column range '%s'\n",
+ indexcol_+1, onlycols_.RangeArg());
+ return 1;
+ }
}
// Determine the type of data stored in each column. Assume numbers should
// be read with double precision.
MetaData md( dsname );
DataSetList::DataListType inputSets;
+ unsigned int nsets = 0;
for (int col = 0; col != ntoken; ++col) {
- md.SetIdx( col+1 );
- if (hasLabels) md.SetLegend( labels[col] );
std::string token( buffer.NextToken() );
- if (validInteger(token) || validDouble(token)) {
- // Number
- inputSets.push_back( new DataSet_double() );
+ if (!onlycols_.Empty() && !onlycols_.InRange( col )) {
+ mprintf("\tSkipping column %i\n", col+1);
+ inputSets.push_back( 0 );
} else {
- // Assume string. Not allowed for index column.
- if (col == indexcol_) {
- mprintf("Warning: '%s' index column %i has string values. No indices will be read.\n",
- buffer.Filename().full(), indexcol_+1);
- indexcol_ = -1;
+ md.SetIdx( col+1 );
+ if (hasLabels) md.SetLegend( labels[col] );
+ if ( col == indexcol_ ) {
+ // Always save the index column as floating point
+ inputSets.push_back( new DataSet_double() );
+ } else if (validInteger(token)) {
+ // Integer number
+ inputSets.push_back( datasetlist.Allocate(DataSet::INTEGER) );
+ } else if (validDouble(token)) {
+ // Floating point number
+ inputSets.push_back( new DataSet_double() );
+ } else {
+ // Assume string. Not allowed for index column.
+ if (col == indexcol_) {
+ mprintf("Warning: '%s' index column %i has string values. No indices will be read.\n",
+ buffer.Filename().full(), indexcol_+1);
+ indexcol_ = -1;
+ }
+ inputSets.push_back( new DataSet_string() );
}
- inputSets.push_back( new DataSet_string() );
+ inputSets.back()->SetMeta( md );
+ nsets++;
}
- inputSets.back()->SetMeta( md );
}
- if (inputSets.empty()) {
+ if (inputSets.empty() || nsets == 0) {
mprinterr("Error: No data detected.\n");
return 1;
}
@@ -262,10 +290,14 @@ int DataIO_Std::Read_1D(std::string const& fname,
// Convert data in columns
for (int i = 0; i < ntoken; ++i) {
const char* token = buffer.NextToken();
- if (inputSets[i]->Type() == DataSet::DOUBLE)
- ((DataSet_double*)inputSets[i])->AddElement( atof(token) );
- else
- ((DataSet_string*)inputSets[i])->AddElement( std::string(token) );
+ if (inputSets[i] != 0) {
+ if (inputSets[i]->Type() == DataSet::DOUBLE)
+ ((DataSet_double*)inputSets[i])->AddElement( atof(token) );
+ else if (inputSets[i]->Type() == DataSet::INTEGER)
+ ((DataSet_integer*)inputSets[i])->AddElement( atoi(token) );
+ else
+ ((DataSet_string*)inputSets[i])->AddElement( std::string(token) );
+ }
}
//Ndata++;
linebuffer = buffer.Line();
@@ -277,11 +309,15 @@ int DataIO_Std::Read_1D(std::string const& fname,
// Create list containing only data sets.
DataSetList::DataListType mySets;
DataSet_double* Xptr = 0;
- for (int idx = 0; idx != (int)inputSets.size(); idx++)
- if ( idx != indexcol_ )
- mySets.push_back( inputSets[idx] );
- else
- Xptr = (DataSet_double*)inputSets[idx];
+ for (int idx = 0; idx != (int)inputSets.size(); idx++) {
+ if (inputSets[idx] != 0) {
+ if ( idx != indexcol_ )
+ mySets.push_back( inputSets[idx] );
+ else
+ Xptr = (DataSet_double*)inputSets[idx];
+ }
+ }
+ mprintf("\tRead %zu data sets.\n", mySets.size());
std::string Xlabel;
if (indexcol_ != -1 && indexcol_ < labels.Nargs())
Xlabel = labels[indexcol_];
diff --git a/src/DataIO_Std.h b/src/DataIO_Std.h
index 78270c7fd7..6bbfc2eb66 100644
--- a/src/DataIO_Std.h
+++ b/src/DataIO_Std.h
@@ -42,6 +42,7 @@ class DataIO_Std : public DataIO {
precType prec_; ///< 3d reads, data set precision
GroupType group_; ///< 1D, control data set grouping
int indexcol_; ///< Read: column containing index (X) values
+ Range onlycols_; ///< 1D reads, columns to read
bool isInverted_; ///< For 1D writes invert X/Y.
bool hasXcolumn_;
bool writeHeader_;
diff --git a/src/DataSet.cpp b/src/DataSet.cpp
index ce2d992732..3fa4af9bfa 100644
--- a/src/DataSet.cpp
+++ b/src/DataSet.cpp
@@ -1,6 +1,36 @@
#include "DataSet.h"
#include "CpptrajStdio.h"
+// NOTE: IT IS IMPORTANT THAT THIS ARRAY CORRESPOND TO DataSet::DataType
+/** Description of each DataType. */
+const char* DataSet::Descriptions_[] = {
+ "unknown", // UNKNOWN_DATA
+ "double", // DOUBLE
+ "float", // FLOAT
+ "integer", // INTEGER
+ "string", // STRING
+ "double matrix", // MATRIX_DBL
+ "float matrix", // MATRIX_FLT
+ "coordinates", // COORDS
+ "vector", // VECTOR
+ "eigenmodes", // MODES
+ "float grid", // GRID_FLT
+ "double grid", // GRID_DBL
+ "remlog", // REMLOG
+ "X-Y mesh", // XYMESH
+ "trajectories", // TRAJ
+ "reference", // REF_FRAME
+ "3x3 matrices", // MAT3X3
+ "topology", // TOPOLOGY
+ "cluster matrix", // CMATRIX
+ "cluster matrix (no memory)", // CMATRIX_NOMEM
+ "cluster matrix (disk)", // CMATRIX_DISK
+ "pH", // PH
+ "pH REMD (explicit)", // PH_EXPL
+ "pH REMD (implicit)", // PH_IMPL
+ "parameters" // PARAMETERS
+};
+
// CONSTRUCTOR
DataSet::DataSet() : dType_(UNKNOWN_DATA), dGroup_(GENERIC)
# ifdef MPI
diff --git a/src/DataSet.h b/src/DataSet.h
index 4e80b7d914..54a36b5b4d 100644
--- a/src/DataSet.h
+++ b/src/DataSet.h
@@ -63,7 +63,8 @@ class DataSet {
virtual void Add( size_t, const void* ) = 0;
/// Can be used to append given data set to this one.
virtual int Append(DataSet*) = 0;
- // TODO SizeInMB?
+ /// \return Size of data set in memory (in bytes).
+ virtual size_t MemUsageInBytes() const = 0;
# ifdef MPI
/// Piece this DataSet together from multiple threads.
virtual int Sync(size_t, std::vector const&, Parallel::Comm const&) = 0;
@@ -122,6 +123,8 @@ class DataSet {
return *first < *second;
}
};
+ /// \return Text description based on DataType
+ static const char* description(DataType t) { return Descriptions_[t]; }
protected:
TextFormat format_; ///< Text output data format.
private:
@@ -132,6 +135,8 @@ class DataSet {
/// Clear any associated data.
void ClearAssociatedData();
+ /// Text descriptions of DataType
+ static const char* Descriptions_[];
// FIXME dim_ and associated functions like Coord need to be reworked
// depending on the set type. For example, dim_ doesnt really work
// for non-orthogonal grids.
diff --git a/src/DataSetList.cpp b/src/DataSetList.cpp
index 17181532da..f790ae6428 100644
--- a/src/DataSetList.cpp
+++ b/src/DataSetList.cpp
@@ -5,7 +5,10 @@
// Data types go here
#include "DataSet_double.h"
#include "DataSet_float.h"
-#include "DataSet_integer.h"
+#include "DataSet_integer_mem.h"
+#ifdef BINTRAJ
+#include "DataSet_integer_disk.h"
+#endif
#include "DataSet_string.h"
#include "DataSet_MatrixDbl.h"
#include "DataSet_MatrixFlt.h"
@@ -28,35 +31,63 @@
#include "DataSet_PHREMD_Implicit.h"
#include "DataSet_Parameters.h"
-// IMPORTANT: THIS ARRAY MUST CORRESPOND TO DataSet::DataType
-const DataSetList::DataToken DataSetList::DataArray[] = {
- { "unknown", 0 }, // UNKNOWN_DATA
- { "double", DataSet_double::Alloc }, // DOUBLE
- { "float", DataSet_float::Alloc }, // FLOAT
- { "integer", DataSet_integer::Alloc }, // INTEGER
- { "string", DataSet_string::Alloc }, // STRING
- { "double matrix", DataSet_MatrixDbl::Alloc }, // MATRIX_DBL
- { "float matrix", DataSet_MatrixFlt::Alloc }, // MATRIX_FLT
- { "coordinates", DataSet_Coords_CRD::Alloc }, // COORDS
- { "vector", DataSet_Vector::Alloc }, // VECTOR
- { "eigenmodes", DataSet_Modes::Alloc }, // MODES
- { "float grid", DataSet_GridFlt::Alloc }, // GRID_FLT
- { "double grid", DataSet_GridDbl::Alloc }, // GRID_DBL
- { "remlog", DataSet_RemLog::Alloc }, // REMLOG
- { "X-Y mesh", DataSet_Mesh::Alloc }, // XYMESH
- { "trajectories", DataSet_Coords_TRJ::Alloc }, // TRAJ
- { "reference", DataSet_Coords_REF::Alloc }, // REF_FRAME
- { "3x3 matrices", DataSet_Mat3x3::Alloc }, // MAT3X3
- { "topology", DataSet_Topology::Alloc }, // TOPOLOGY
- { "cluster matrix",DataSet_Cmatrix_MEM::Alloc}, // CMATRIX
- { "cluster matrix (no memory)",DataSet_Cmatrix_NOMEM::Alloc}, // CMATRIX_NOMEM
- { "cluster matrix (disk)", DataSet_Cmatrix_DISK::Alloc}, // CMATRIX_DISK
- { "pH", DataSet_pH::Alloc }, // PH
- { "pH REMD (explicit)",DataSet_PHREMD_Explicit::Alloc}, // PH_EXPL
- { "pH REMD (implicit)",DataSet_PHREMD_Implicit::Alloc}, // PH_IMPL
- { "parameters", DataSet_Parameters::Alloc }, // PARAMETERS
- { 0, 0 }
-};
+bool DataSetList::useDiskCache_ = false;
+
+/** Master data set allocation routine. */
+DataSet* DataSetList::NewSet(DataSet::DataType typeIn) {
+ DataSet* ds = 0;
+ bool cannotUseDiskCache = true; // Most cannot.
+ switch (typeIn) {
+ case DataSet::UNKNOWN_DATA :
+ mprinterr("Internal Error: DataSetList::NewSet() called with no type.\n"); break;
+ case DataSet::DOUBLE : ds = DataSet_double::Alloc(); break;
+ case DataSet::FLOAT : ds = DataSet_float::Alloc(); break;
+ case DataSet::INTEGER :
+# ifdef BINTRAJ
+ if (useDiskCache_) {
+ ds = DataSet_integer_disk::Alloc();
+ cannotUseDiskCache = false;
+ } else
+ ds = DataSet_integer_mem::Alloc();
+# else
+ if (useDiskCache_)
+ mprintf("Warning: Integer data set disk cache requires NetCDF. Using memory.\n"
+ ds = DataSet_integer_mem::Alloc();
+# endif
+ break;
+ case DataSet::STRING : ds = DataSet_string::Alloc(); break;
+ case DataSet::MATRIX_DBL : ds = DataSet_MatrixDbl::Alloc(); break;
+ case DataSet::MATRIX_FLT : ds = DataSet_MatrixFlt::Alloc(); break;
+ case DataSet::COORDS : ds = DataSet_Coords_CRD::Alloc(); break;
+ case DataSet::VECTOR : ds = DataSet_Vector::Alloc() ; break;
+ case DataSet::MODES : ds = DataSet_Modes::Alloc(); break;
+ case DataSet::GRID_FLT : ds = DataSet_GridFlt::Alloc(); break;
+ case DataSet::GRID_DBL : ds = DataSet_GridDbl::Alloc(); break;
+ case DataSet::REMLOG : ds = DataSet_RemLog::Alloc(); break;
+ case DataSet::XYMESH : ds = DataSet_Mesh::Alloc(); break;
+ case DataSet::TRAJ : ds = DataSet_Coords_TRJ::Alloc(); break;
+ case DataSet::REF_FRAME : ds = DataSet_Coords_REF::Alloc(); break;
+ case DataSet::MAT3X3 : ds = DataSet_Mat3x3::Alloc(); break;
+ case DataSet::TOPOLOGY : ds = DataSet_Topology::Alloc(); break;
+ case DataSet::CMATRIX : ds = DataSet_Cmatrix_MEM::Alloc(); break;
+ case DataSet::CMATRIX_NOMEM : ds = DataSet_Cmatrix_NOMEM::Alloc(); break;
+ case DataSet::CMATRIX_DISK : ds = DataSet_Cmatrix_DISK::Alloc(); break;
+ case DataSet::PH : ds = DataSet_pH::Alloc(); break;
+ case DataSet::PH_EXPL : ds = DataSet_PHREMD_Explicit::Alloc(); break;
+ case DataSet::PH_IMPL : ds = DataSet_PHREMD_Implicit::Alloc(); break;
+ case DataSet::PARAMETERS : ds = DataSet_Parameters::Alloc(); break;
+ // Sanity check
+ default:
+ mprinterr("Internal Error: No allocator for DataSet type '%s'\n",
+ DataSet::description(typeIn));
+ }
+ if (ds == 0)
+ mprinterr("Error: Could not allocate DataSet type '%s'\n", DataSet::description(typeIn));
+ else if (useDiskCache_ && cannotUseDiskCache)
+ mprintf("Warning: Use disk cache specified, but DataSet type '%s' cannot use disk caching.\n",
+ DataSet::description(typeIn));
+ return ds;
+}
// CONSTRUCTOR
DataSetList::DataSetList() :
@@ -448,12 +479,7 @@ void DataSetList::Timing() const {
// DataSetList::Allocate()
DataSet* DataSetList::Allocate(DataSet::DataType inType) {
- TokenPtr token = &(DataArray[inType]);
- if ( token->Alloc == 0) {
- mprinterr("Internal Error: No allocator for DataSet type [%s]\n", token->Description);
- return 0;
- }
- return (DataSet*)token->Alloc();
+ return NewSet(inType);
}
// FIXME Should probably just make a more efficient search of DSL
@@ -582,13 +608,13 @@ int DataSetList::AddOrAppendSets(std::string const& XlabelIn, Darray const& Xval
}
if (!canAppend)
mprinterr("Error: Cannot append set of type %s to set of type %s\n",
- DataArray[(*ds)->Type()].Description,
- DataArray[existingSet->Type()].Description);
+ DataSet::description((*ds)->Type()),
+ DataSet::description(existingSet->Type()));
// If cannot append or attempt to append fails, rename and add as new set.
if (!canAppend || existingSet->Append( *ds )) { // TODO Dimension check?
if (canAppend)
mprintf("Warning: Append currently not supported for type %s\n",
- DataArray[existingSet->Type()].Description);
+ DataSet::description(existingSet->Type()));
MetaData md = (*ds)->Meta();
md.SetName( GenerateDefaultName("X") );
mprintf("Warning: Renaming %s to %s\n", (*ds)->Meta().PrintName().c_str(),
@@ -616,11 +642,17 @@ void DataSetList::AddCopyOfSet(DataSet* dsetIn) {
}
void DataSetList::PrintList(DataListType const& dlist) {
+ size_t memTotal = 0;
for (DataListType::const_iterator ds = dlist.begin(); ds != dlist.end(); ++ds) {
DataSet const& dset = static_cast( *(*ds) );
- mprintf("\t%s \"%s\" (%s%s), size is %zu", dset.Meta().PrintName().c_str(), dset.legend(),
- DataArray[dset.Type()].Description, dset.Meta().ScalarDescription().c_str(),
+ mprintf("\t%s \"%s\" (%s%s), size is %zu", dset.Meta().PrintName().c_str(),
+ dset.legend(), DataSet::description(dset.Type()),
+ dset.Meta().ScalarDescription().c_str(),
dset.Size());
+ size_t memUsage = dset.MemUsageInBytes();
+ if (memUsage > 0)
+ mprintf(" (%s)", ByteString(memUsage, BYTE_DECIMAL).c_str());
+ memTotal += memUsage;
dset.Info();
mprintf("\n");
}
@@ -633,7 +665,7 @@ void DataSetList::PrintList(DataListType const& dlist) {
for (DataListType::const_iterator ds = dlist.begin(); ds != dlist.end(); ++ds) {
DataSet const& dset = static_cast( *(*ds) );
rprintf("%s \"%s\" (%s%s), size is %zu\n", dset.Meta().PrintName().c_str(),
- dset.legend(), DataArray[dset.Type()].Description,
+ dset.legend(), DataSet::description(dset.Type()),
dset.Meta().ScalarDescription().c_str(), dset.Size());
}
}
@@ -643,6 +675,7 @@ void DataSetList::PrintList(DataListType const& dlist) {
Parallel::EnsembleComm().Barrier();
}
# endif
+ mprintf(" Total data set memory usage is at least %s\n", ByteString(memTotal, BYTE_DECIMAL).c_str());
}
// DataSetList::List()
diff --git a/src/DataSetList.h b/src/DataSetList.h
index a2997fab23..572088ebf8 100644
--- a/src/DataSetList.h
+++ b/src/DataSetList.h
@@ -56,6 +56,8 @@ class DataSetList {
void SetDataSetsPending(bool b) { dataSetsPending_ = b; }
/// Set whether set has copies (no ds mem free) or not (will free ds mem).
void SetHasCopies(bool b) { hasCopies_ = b; }
+ /// Set whether DataSets should be cached to disk if possible.
+ void SetDiskCache(bool b) { useDiskCache_ = b; }
/// Make all sets not part of an ensemble part of given ensemble.
//void MakeDataSetsEnsemble(int);
/// \return Ensemble number; -1 if not an ensemble
@@ -146,6 +148,8 @@ class DataSetList {
void Timing() const;
# endif
private:
+ /// \return New set of given type.
+ static DataSet* NewSet(DataSet::DataType);
/// Search for and remove specified data set if found, optionally free memory.
DataSet* EraseSet( DataSet*, bool );
/// Warn if DataSet not found but may be pending.
@@ -172,16 +176,10 @@ class DataSetList {
int ensembleNum_; ///< Ensemble member number
bool hasCopies_; ///< True if DataSets should not be freed.
bool dataSetsPending_; ///< True if Actions will generate DataSets in the future.
+ static bool useDiskCache_; ///< If true try to use disk-cached versions of data sets.
DataListType DataList_; ///< List of DataSets
DataListType RefList_; ///< Pointers to reference data sets.
DataListType TopList_; ///< Pointers to topology data sets.
- /// Hold descriptions and allocators for all DataSet types.
- struct DataToken {
- const char* Description;
- DataSet::AllocatorType Alloc;
- };
- static const DataToken DataArray[];
- typedef const DataToken* TokenPtr;
# ifdef MPI
bool newSetsNeedSync_; ///< If true, any sets added need to be synced.
# endif
diff --git a/src/DataSet_1D.h b/src/DataSet_1D.h
index 924d30aa93..b4f9ff60dc 100644
--- a/src/DataSet_1D.h
+++ b/src/DataSet_1D.h
@@ -8,6 +8,7 @@ class DataSet_1D : public DataSet {
DataSet_1D() {}
DataSet_1D(DataSet::DataType tIn, TextFormat const& fIn) : DataSet(tIn, SCALAR_1D, fIn, 1) {}
virtual ~DataSet_1D() {}
+ // ---- DataSet_1D functions -----------------
/// \return data from set at position as double precision.
virtual double Dval(size_t) const = 0;
/// \return the value of the X coordinate at position.
diff --git a/src/DataSet_Cmatrix_DISK.h b/src/DataSet_Cmatrix_DISK.h
index 1472ae7fed..f6c6c5406b 100644
--- a/src/DataSet_Cmatrix_DISK.h
+++ b/src/DataSet_Cmatrix_DISK.h
@@ -12,6 +12,8 @@ class DataSet_Cmatrix_DISK : public DataSet_Cmatrix {
void Info() const { return; }
void WriteBuffer(CpptrajFile&, SizeArray const&) const {}
int Allocate(SizeArray const&) { return 0; }
+ /// \return Size in bytes of set
+ size_t MemUsageInBytes() const { return 0; }
// ----- Cmatrix functions -------------------
/// \return an element indexed by sievedFrames.
inline double GetFdist(int, int) const;
diff --git a/src/DataSet_Cmatrix_MEM.h b/src/DataSet_Cmatrix_MEM.h
index b0c4c3ec99..34c23db56d 100644
--- a/src/DataSet_Cmatrix_MEM.h
+++ b/src/DataSet_Cmatrix_MEM.h
@@ -15,6 +15,8 @@ class DataSet_Cmatrix_MEM : public DataSet_Cmatrix {
void Info() const { return; }
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Allocate(SizeArray const&);
+ /// \return Size in bytes of set
+ size_t MemUsageInBytes() const { return Mat_.DataSize(); }
// ----- Cmatrix functions -------------------
/// \return an element indexed by sievedFrames.
inline double GetFdist(int, int) const;
diff --git a/src/DataSet_Cmatrix_NOMEM.h b/src/DataSet_Cmatrix_NOMEM.h
index 235b143692..13cf7f09b3 100644
--- a/src/DataSet_Cmatrix_NOMEM.h
+++ b/src/DataSet_Cmatrix_NOMEM.h
@@ -12,6 +12,8 @@ class DataSet_Cmatrix_NOMEM : public DataSet_Cmatrix {
void Info() const { return; }
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Allocate(SizeArray const&) { return 0; }
+ /// \return Size in bytes of set
+ size_t MemUsageInBytes() const { return 0; }
// ----- Cmatrix functions -------------------
/// \return an element indexed by sievedFrames.
inline double GetFdist(int f1, int f2) const { return cdist_->FrameDist(f1, f2); }
diff --git a/src/DataSet_Coords_CRD.cpp b/src/DataSet_Coords_CRD.cpp
index 0207d7787e..7205bad3f8 100644
--- a/src/DataSet_Coords_CRD.cpp
+++ b/src/DataSet_Coords_CRD.cpp
@@ -38,12 +38,6 @@ size_t DataSet_Coords_CRD::sizeInBytes(size_t nframes, size_t natom, size_t nbox
return ((nframes * frame_size_bytes) + sizeof(CRDarray));
}
-void DataSet_Coords_CRD::Info() const {
- mprintf(" (%s)",
- ByteString(sizeInBytes(coords_.size(), top_.Natom(), numBoxCrd_), BYTE_DECIMAL).c_str());
- CommonInfo();
-}
-
#ifdef MPI
int DataSet_Coords_CRD::Sync(size_t total, std::vector const& rank_frames,
Parallel::Comm const& commIn)
diff --git a/src/DataSet_Coords_CRD.h b/src/DataSet_Coords_CRD.h
index a0c82998cc..e53c9b98a2 100644
--- a/src/DataSet_Coords_CRD.h
+++ b/src/DataSet_Coords_CRD.h
@@ -10,9 +10,11 @@ class DataSet_Coords_CRD : public DataSet_Coords {
# ifdef MPI
int Sync(size_t, std::vector const&, Parallel::Comm const&);
# endif
- void Info() const;
+ void Info() const { return; }
void Add(size_t, const void*) {}
int Allocate(SizeArray const&);
+ /// \return Size in bytes of set
+ size_t MemUsageInBytes() const { return EstSizeInBytes(Size()); }
// ----- DataSet_Coords functions ------------
/// Add a frame.
inline void AddFrame(Frame const& fIn) {
@@ -34,7 +36,7 @@ class DataSet_Coords_CRD : public DataSet_Coords {
int CoordsSetup(Topology const&, CoordinateInfo const&);
// -------------------------------------------
/// \return estimated size in bytes for given # of frames.
- size_t SizeInBytes(size_t n) const { return sizeInBytes(n, Top().Natom(), numBoxCrd_); }
+ size_t EstSizeInBytes(size_t nframes) const { return sizeInBytes(nframes, Top().Natom(), numBoxCrd_); }
private:
static size_t sizeInBytes(size_t, size_t, size_t);
diff --git a/src/DataSet_Coords_REF.h b/src/DataSet_Coords_REF.h
index 9ed8bcf4bb..f9cdf2f7e1 100644
--- a/src/DataSet_Coords_REF.h
+++ b/src/DataSet_Coords_REF.h
@@ -17,6 +17,7 @@ class DataSet_Coords_REF : public DataSet_Coords {
void Add( size_t, const void* ) { return; }
// Size is only ever 1, no need to allocate.
int Allocate(SizeArray const&) { return 0; }
+ size_t MemUsageInBytes() const { return frame_.DataSize(); }
// ----- DataSet_Coords functions ------------
/// Add a frame.
inline void AddFrame(Frame const& fIn) { frame_ = fIn; }
diff --git a/src/DataSet_Coords_TRJ.h b/src/DataSet_Coords_TRJ.h
index 319879e4de..47464ff786 100644
--- a/src/DataSet_Coords_TRJ.h
+++ b/src/DataSet_Coords_TRJ.h
@@ -22,6 +22,7 @@ class DataSet_Coords_TRJ : public DataSet_Coords {
void Info() const;
void Add( size_t, const void* ) { return; }
int Allocate(SizeArray const&) { return 0; }
+ size_t MemUsageInBytes() const { return IDX_.DataSize() + readFrame_.DataSize(); } // FIXME
// ----- DataSet_Coords functions ------------
/// DISABLED: Add a frame.
void AddFrame(Frame const& fIn) { }
diff --git a/src/DataSet_GridDbl.cpp b/src/DataSet_GridDbl.cpp
index f8d2c4a8bf..3f45fc2a12 100644
--- a/src/DataSet_GridDbl.cpp
+++ b/src/DataSet_GridDbl.cpp
@@ -14,10 +14,6 @@ void DataSet_GridDbl::WriteBuffer(CpptrajFile& outfile, SizeArray const& pIn) co
outfile.Printf(format_.fmt(), grid_.element(x,y,z));
}
-void DataSet_GridDbl::Info() const {
- mprintf(" (%s)", ByteString(Grid::sizeInBytes(NX(), NY(), NZ()), BYTE_DECIMAL).c_str());
-}
-
#ifdef MPI
int DataSet_GridDbl::Sync(size_t total, std::vector const& rank_frames,
Parallel::Comm const& commIn)
diff --git a/src/DataSet_GridDbl.h b/src/DataSet_GridDbl.h
index fe7f203524..16aa2cd20d 100644
--- a/src/DataSet_GridDbl.h
+++ b/src/DataSet_GridDbl.h
@@ -16,8 +16,9 @@ class DataSet_GridDbl : public DataSet_3D {
// FIXME: Currently just sums up. Should this be a separate Sync function?
int Sync(size_t, std::vector const&, Parallel::Comm const&);
# endif
- void Info() const;
+ void Info() const { return; }
void WriteBuffer(CpptrajFile&,SizeArray const&) const;
+ size_t MemUsageInBytes() const { return grid_.DataSize(); }
// ----- DataSet_3D functions ----------------
int Allocate3D(size_t x,size_t y,size_t z) { return grid_.resize(x,y,z); }
double GetElement(size_t x,size_t y,size_t z) const { return grid_.element(x,y,z); }
diff --git a/src/DataSet_GridFlt.cpp b/src/DataSet_GridFlt.cpp
index cc39ca26a8..c2875f97ee 100644
--- a/src/DataSet_GridFlt.cpp
+++ b/src/DataSet_GridFlt.cpp
@@ -14,10 +14,6 @@ void DataSet_GridFlt::WriteBuffer(CpptrajFile& outfile, SizeArray const& pIn) co
outfile.Printf(format_.fmt(), grid_.element(x,y,z));
}
-void DataSet_GridFlt::Info() const {
- mprintf(" (%s)", ByteString(Grid::sizeInBytes(NX(), NY(), NZ()), BYTE_DECIMAL).c_str());
-}
-
#ifdef MPI
int DataSet_GridFlt::Sync(size_t total, std::vector const& rank_frames,
Parallel::Comm const& commIn)
diff --git a/src/DataSet_GridFlt.h b/src/DataSet_GridFlt.h
index 6e41c13987..64a00db309 100644
--- a/src/DataSet_GridFlt.h
+++ b/src/DataSet_GridFlt.h
@@ -16,8 +16,9 @@ class DataSet_GridFlt : public DataSet_3D {
// FIXME: Currently just sums up. Should this be a separate Sync function?
int Sync(size_t, std::vector const&, Parallel::Comm const&);
# endif
- void Info() const;
+ void Info() const { return; }
void WriteBuffer(CpptrajFile&,SizeArray const&) const;
+ size_t MemUsageInBytes() const { return grid_.DataSize(); }
// ----- DataSet_3D functions ----------------
int Allocate3D(size_t x, size_t y, size_t z) { return grid_.resize(x,y,z); }
double GetElement(size_t x, size_t y, size_t z) const { return (double)grid_.element(x,y,z); }
diff --git a/src/DataSet_Mat3x3.h b/src/DataSet_Mat3x3.h
index 945cc9eee8..b460c2bea6 100644
--- a/src/DataSet_Mat3x3.h
+++ b/src/DataSet_Mat3x3.h
@@ -18,6 +18,7 @@ class DataSet_Mat3x3 : public DataSet {
inline void Add(size_t, const void*);
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Append(DataSet*);
+ size_t MemUsageInBytes() const { return (9 * data_.size() * sizeof(double)); }
// -------------------------------------------
void AddMat3x3( Matrix_3x3 const& m) { data_.push_back( m ); }
typedef Marray::const_iterator const_iterator;
diff --git a/src/DataSet_MatrixDbl.h b/src/DataSet_MatrixDbl.h
index ab13fc12ec..e2166f87a0 100644
--- a/src/DataSet_MatrixDbl.h
+++ b/src/DataSet_MatrixDbl.h
@@ -19,6 +19,7 @@ class DataSet_MatrixDbl : public DataSet_2D {
# endif
void Info() const { return; }
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
+ size_t MemUsageInBytes() const { return mat_.DataSize(); }
// ----- DataSet_2D functions ----------------
void UpdateElement(size_t x,size_t y,double v) { mat_.updateElement(x,y,v); }
int Allocate2D(size_t x,size_t y) { kind_=FULL; return mat_.resize(x,y); }
diff --git a/src/DataSet_MatrixFlt.h b/src/DataSet_MatrixFlt.h
index 90ab289fce..f0c71ad752 100644
--- a/src/DataSet_MatrixFlt.h
+++ b/src/DataSet_MatrixFlt.h
@@ -18,6 +18,7 @@ class DataSet_MatrixFlt : public DataSet_2D {
# endif
void Info() const { return; }
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
+ size_t MemUsageInBytes() const { return mat_.DataSize(); }
// ----- DataSet_2D functions ----------------
void UpdateElement(size_t x,size_t y,double v) { mat_.updateElement(x,y,v); }
int Allocate2D(size_t x,size_t y) { kind_=FULL; return mat_.resize(x,y); }
@@ -36,7 +37,6 @@ class DataSet_MatrixFlt : public DataSet_2D {
typedef Matrix::iterator iterator;
iterator begin() { return mat_.begin(); }
iterator end() { return mat_.end(); }
- size_t SizeInBytes() { return mat_.sizeInBytes(Ncols(), Nrows()); }
private:
Matrix mat_;
MatrixKindType kind_;
diff --git a/src/DataSet_Mesh.h b/src/DataSet_Mesh.h
index 1e0ec03d33..814b4d732e 100644
--- a/src/DataSet_Mesh.h
+++ b/src/DataSet_Mesh.h
@@ -22,6 +22,7 @@ class DataSet_Mesh : public DataSet_1D {
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Append(DataSet*);
double Coord(unsigned int d, size_t p) const { return mesh_x_[p]; }
+ size_t MemUsageInBytes() const { return ((mesh_x_.size() + mesh_y_.size()) * sizeof(double)) + cspline_.DataSize(); }
// ----- DataSet_1D functions ----------------
double Dval(size_t idx) const { return mesh_y_[idx]; }
double Xcrd(size_t idx) const { return mesh_x_[idx]; }
diff --git a/src/DataSet_Modes.cpp b/src/DataSet_Modes.cpp
index aadb8ba88e..8f8fe146d9 100644
--- a/src/DataSet_Modes.cpp
+++ b/src/DataSet_Modes.cpp
@@ -42,6 +42,20 @@ DataSet_Modes::~DataSet_Modes() {
if (evectors_!=0) delete[] evectors_;
}
+/** \return current memory usage in bytes. */
+size_t DataSet_Modes::MemUsageInBytes() const {
+ size_t mySize = (avgcrd_.size() * sizeof(double)) +
+ (mass_.size() * sizeof(double)) +
+ (2 * sizeof(double*)) +
+ (2 * sizeof(int)) +
+ (3 * sizeof(bool));
+ if (evalues_ != 0)
+ mySize += (nmodes_ * sizeof(double));
+ if (evectors_ != 0)
+ mySize += (nmodes_ * vecsize_ * sizeof(double));
+ return mySize;
+}
+
// DataSet_Modes::SetAvgCoords()
int DataSet_Modes::SetAvgCoords(DataSet_2D const& mIn) {
avgcrd_.clear();
diff --git a/src/DataSet_Modes.h b/src/DataSet_Modes.h
index 2ba4fccc3a..796bb44d57 100644
--- a/src/DataSet_Modes.h
+++ b/src/DataSet_Modes.h
@@ -18,6 +18,7 @@ class DataSet_Modes : public DataSet {
void WriteBuffer(CpptrajFile&, SizeArray const&) const {} // TODO implement?
int Allocate(SizeArray const&) { return 0; } // TODO implement?
int Append(DataSet*) { return 1; }
+ size_t MemUsageInBytes() const;
// -------------------------------------------
typedef std::vector Darray;
typedef Darray::const_iterator AvgIt;
diff --git a/src/DataSet_PHREMD_Explicit.h b/src/DataSet_PHREMD_Explicit.h
index 45c5431016..b4a78816ed 100644
--- a/src/DataSet_PHREMD_Explicit.h
+++ b/src/DataSet_PHREMD_Explicit.h
@@ -15,6 +15,9 @@ class DataSet_PHREMD_Explicit : public DataSet_PHREMD {
int Allocate(SizeArray const&);
void Add( size_t, const void* ) { return; }
int Append(DataSet*) { return 1; }
+ size_t MemUsageInBytes() const { return (solvent_pH_.size() * sizeof(float)) +
+ (recType_.size() * sizeof(int)) +
+ (resStates_.size() * sizeof(int)); }
# ifdef MPI
int Sync(size_t, std::vector const&, Parallel::Comm const&) { return 1; }
//void Reduce(Parallel::Comm const&, int);
diff --git a/src/DataSet_PHREMD_Implicit.cpp b/src/DataSet_PHREMD_Implicit.cpp
index 0ca8966478..8c1222a876 100644
--- a/src/DataSet_PHREMD_Implicit.cpp
+++ b/src/DataSet_PHREMD_Implicit.cpp
@@ -6,6 +6,13 @@ DataSet_PHREMD_Implicit::DataSet_PHREMD_Implicit() :
DataSet_PHREMD(PH_IMPL, TextFormat(TextFormat::DOUBLE, 10, 4))
{}
+size_t DataSet_PHREMD_Implicit::MemUsageInBytes() const {
+ size_t mySize = 0;
+ for (RecArray::const_iterator it = records_.begin(); it != records_.end(); ++it)
+ mySize += it->DataSize();
+ return mySize;
+}
+
int DataSet_PHREMD_Implicit::Allocate(SizeArray const& sizeIn) {
if (!sizeIn.empty()) records_.reserve( sizeIn[0] );
return 0;
diff --git a/src/DataSet_PHREMD_Implicit.h b/src/DataSet_PHREMD_Implicit.h
index 3871bf644a..233e8f900b 100644
--- a/src/DataSet_PHREMD_Implicit.h
+++ b/src/DataSet_PHREMD_Implicit.h
@@ -13,6 +13,7 @@ class DataSet_PHREMD_Implicit : public DataSet_PHREMD {
void Add(size_t, const void*) { return; }
void WriteBuffer(CpptrajFile&, SizeArray const&) const { return; }
int Append(DataSet*) { return 1; }
+ size_t MemUsageInBytes() const;
# ifdef MPI
int Sync(size_t, std::vector const&, Parallel::Comm const&) { return 1; }
# endif
@@ -30,6 +31,7 @@ class DataSet_PHREMD_Implicit : public DataSet_PHREMD {
float pH() const { return pH_; }
int RecType() const { return recType_; }
Iarray const& ResStates() const { return resStates_; }
+ size_t DataSize() const { return sizeof(int)+sizeof(float)+(resStates_.size()*sizeof(int)); }
private:
float pH_; ///< solvent pH
int recType_; ///< Record type
diff --git a/src/DataSet_Parameters.cpp b/src/DataSet_Parameters.cpp
index f29a172db1..4fe7e0be6d 100644
--- a/src/DataSet_Parameters.cpp
+++ b/src/DataSet_Parameters.cpp
@@ -6,6 +6,15 @@ DataSet_Parameters::DataSet_Parameters() :
DataSet(PARAMETERS, GENERIC, TextFormat(), 0)
{}
+size_t DataSet_Parameters::MemUsageInBytes() const {
+ return (atomTypes_.DataSize() +
+ bondParm_.DataSize() +
+ angleParm_.DataSize() +
+ ubParm_.DataSize() +
+ dihParm_.DataSize() +
+ impParm_.DataSize());
+}
+
size_t DataSet_Parameters::Size() const {
return (atomTypes_.Size() +
bondParm_.size() +
diff --git a/src/DataSet_Parameters.h b/src/DataSet_Parameters.h
index 4cef528531..7d32a37310 100644
--- a/src/DataSet_Parameters.h
+++ b/src/DataSet_Parameters.h
@@ -19,6 +19,7 @@ class DataSet_Parameters : public DataSet {
# ifdef MPI
int Sync(size_t, std::vector const&, Parallel::Comm const&) { return 1; }
# endif
+ size_t MemUsageInBytes() const;
// -------------------------------------------
AtomTypeArray& AT() { return atomTypes_; }
ParmHolder& BP() { return bondParm_; }
diff --git a/src/DataSet_RemLog.cpp b/src/DataSet_RemLog.cpp
index 8422d13567..0201d7bd07 100644
--- a/src/DataSet_RemLog.cpp
+++ b/src/DataSet_RemLog.cpp
@@ -8,6 +8,25 @@ DataSet_RemLog::DataSet_RemLog() :
wrap_(false)
{}
+size_t DataSet_RemLog::MemUsageInBytes() const {
+ size_t mySize = (finalCrdIdx_.size() * sizeof(int)) +
+ repDims_.DataSize() +
+ sizeof(int) +
+ sizeof(bool);
+ for (ReplicaEnsemble::const_iterator rep = ensemble_.begin();
+ rep != ensemble_.end(); ++rep)
+ mySize += (rep->size() * ReplicaFrame::DataSize());
+ for (GdimArray::const_iterator dim = groupDims_.begin();
+ dim != groupDims_.end(); ++dim)
+ for (GroupDimType::const_iterator grp = dim->begin();
+ grp != dim->end(); ++grp)
+ mySize += (grp->size() * GroupReplica::DataSize());
+ for (RepInfoArray::const_iterator rep = repInfo_.begin();
+ rep != repInfo_.end(); ++rep)
+ mySize += (rep->size() * RepInfo::DataSize());
+ return mySize;
+}
+
/** Setup a single 1-dimension group.
* \param group_size Expected number of replicas.
*/
diff --git a/src/DataSet_RemLog.h b/src/DataSet_RemLog.h
index b9d395c193..efc60033fe 100644
--- a/src/DataSet_RemLog.h
+++ b/src/DataSet_RemLog.h
@@ -71,6 +71,7 @@ class DataSet_RemLog : public DataSet {
// TODO: Remove
void Add( size_t, const void* ) { return; }
int Append(DataSet*) { return 1; }
+ size_t MemUsageInBytes() const;
// -------------------------------------------
private:
/// Hold info for all exchanges of a single replica.
@@ -107,6 +108,7 @@ class DataSet_RemLog::ReplicaFrame {
double Temp0() const { return temp0_; }
double PE_X1() const { return PE_x1_; }
double PE_X2() const { return PE_x2_; }
+ static size_t DataSize() { return 3*sizeof(double)+4*sizeof(int)*sizeof(bool); }
private:
double temp0_; ///< Replica bath temperature.
double PE_x1_; ///< (HREMD) Potential energy with coords 1.
@@ -128,6 +130,7 @@ class DataSet_RemLog::GroupReplica {
int L_partner() const { return l_partner_; }
int Me() const { return me_; }
int R_partner() const { return r_partner_; }
+ static size_t DataSize() { return 3*sizeof(int); }
private:
int l_partner_, me_, r_partner_;
};
@@ -141,6 +144,7 @@ class DataSet_RemLog::RepInfo {
int LeftID() const { return lp_; }
int RightID() const { return rp_; }
LocationType Location() const { return loc_; }
+ static size_t DataSize() { return 4*sizeof(int); }
private:
int grp_; ///< Group this replica belongs to in this dim
int lp_; ///< Left partner of this replica in this dim
diff --git a/src/DataSet_Topology.h b/src/DataSet_Topology.h
index 73174463dd..fcdbef4e55 100644
--- a/src/DataSet_Topology.h
+++ b/src/DataSet_Topology.h
@@ -17,6 +17,7 @@ class DataSet_Topology : public DataSet {
void Add( size_t, const void* ) {}
void WriteBuffer(CpptrajFile&, SizeArray const&) const {}
int Append(DataSet*) { return 1; }
+ size_t MemUsageInBytes() const { return 0; } // FIXME
// -------------------------------------------
int LoadTopFromFile(ArgList const&, int);
int StripTop( std::string const& );
diff --git a/src/DataSet_Vector.cpp b/src/DataSet_Vector.cpp
index a9a707cd53..152c9abd00 100644
--- a/src/DataSet_Vector.cpp
+++ b/src/DataSet_Vector.cpp
@@ -12,6 +12,18 @@ DataSet_Vector::DataSet_Vector() :
DataSet(VECTOR, GENERIC, TextFormat(TextFormat::DOUBLE, 8, 4, 6), 1),
order_(0) {}
+size_t DataSet_Vector::MemUsageInBytes() const {
+ size_t mySize = (vectors_.size() * Vec3::DataSize()) +
+ (origins_.size() * Vec3::DataSize()) +
+ sizeof(int);
+ for (std::vector::const_iterator SH = sphericalHarmonics_.begin();
+ SH != sphericalHarmonics_.end();
+ ++SH)
+ mySize += (SH->DataSize());
+ return mySize;
+}
+
+
// DataSet_Vector::Allocate()
int DataSet_Vector::Allocate(SizeArray const& Nin) {
if (!Nin.empty()) {
diff --git a/src/DataSet_Vector.h b/src/DataSet_Vector.h
index 793a3328f0..ae05b7ba15 100644
--- a/src/DataSet_Vector.h
+++ b/src/DataSet_Vector.h
@@ -22,6 +22,7 @@ class DataSet_Vector : public DataSet {
inline void Add(size_t, const void*);
void WriteBuffer(CpptrajFile&,SizeArray const&) const;
int Append( DataSet* );
+ size_t MemUsageInBytes() const;
// -------------------------------------------
void reset();
void Resize(size_t s) { vectors_.resize( s ); }
diff --git a/src/DataSet_double.h b/src/DataSet_double.h
index c5a709c5bb..4f29c47d56 100644
--- a/src/DataSet_double.h
+++ b/src/DataSet_double.h
@@ -30,6 +30,7 @@ class DataSet_double : public DataSet_1D {
void Add( size_t, const void* );
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Append(DataSet*);
+ size_t MemUsageInBytes() const { return Data_.size() * sizeof(double); }
// ----- DataSet_1D functions ----------------
double Dval(size_t idx) const { return Data_[idx]; }
double Xcrd(size_t idx) const { return Dim(0).Coord(idx); }
diff --git a/src/DataSet_float.h b/src/DataSet_float.h
index fed6b0c100..3c56d407bd 100644
--- a/src/DataSet_float.h
+++ b/src/DataSet_float.h
@@ -24,6 +24,7 @@ class DataSet_float : public DataSet_1D {
void Add( size_t, const void* );
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Append(DataSet*);
+ size_t MemUsageInBytes() const { return Data_.size() * sizeof(float); }
// ----- DataSet_1D functions ----------------
double Dval(size_t idx) const { return (double)Data_[idx]; }
double Xcrd(size_t idx) const { return Dim(0).Coord(idx); }
diff --git a/src/DataSet_integer.h b/src/DataSet_integer.h
index f83d0b7f68..34fdbc8c09 100644
--- a/src/DataSet_integer.h
+++ b/src/DataSet_integer.h
@@ -1,47 +1,31 @@
#ifndef INC_DATASET_INTEGER_H
#define INC_DATASET_INTEGER_H
-#include
#include "DataSet_1D.h"
-/// Hold an array of integer values.
+/// Base class for integer 1D data sets
class DataSet_integer : public DataSet_1D {
public:
DataSet_integer() : DataSet_1D(INTEGER, TextFormat(TextFormat::INTEGER, 12)) {}
- static DataSet* Alloc() { return (DataSet*)new DataSet_integer();}
- int& operator[](size_t idx) { return Data_[idx]; }
- int operator[](size_t idx) const { return Data_[idx]; }
- void AddElement(int i) { Data_.push_back( i ); }
+ virtual ~DataSet_integer() {} // Virtual bc inherited
+ //static DataSet* Alloc() { return (DataSet*)new DataSet_integer();} TODO fix
+ //virtual int& operator[](size_t) = 0;
+ virtual void SetElement(size_t, int) = 0;
+ virtual int operator[](size_t) const = 0;
+ virtual void AddElement(int) = 0;
/// Make set size sizeIn, all values set to 0.0.
- void Resize(size_t sizeIn) { Data_.resize(sizeIn, 0); }
- inline void AddVal(size_t, int);
- // ----- DataSet functions -------------------
- size_t Size() const { return Data_.size(); }
+ virtual void Resize(size_t) = 0;
+ /// Make set size sizeIn, all values set to val.
+ virtual void Assign(size_t,int) = 0;
+ virtual void AddVal(size_t, int) = 0;
# ifdef MPI
- int Sync(size_t, std::vector const&, Parallel::Comm const&);
+ virtual int Recv(size_t, unsigned int, int, int, int, Parallel::Comm const&) { return 1; }
+ virtual int Send(int, int, Parallel::Comm const&) const { return 1; }
# endif
- void Info() const { return; }
- int Allocate(SizeArray const&);
- void Add( size_t, const void* );
- void WriteBuffer(CpptrajFile&, SizeArray const&) const;
- int Append(DataSet*);
// ----- DataSet_1D functions ----------------
- double Dval(size_t idx) const { return (double)Data_[idx]; }
double Xcrd(size_t idx) const { return Dim(0).Coord(idx); }
- const void* VoidPtr(size_t idx) const { return (void*)(&(Data_[0])+idx); }
// -------------------------------------------
- typedef std::vector::iterator iterator;
- iterator begin() { return Data_.begin(); }
- iterator end() { return Data_.end(); }
- int* Ptr() { return &(Data_[0]); }
- private:
- std::vector Data_;
+ //typedef std::vector::iterator iterator;
+ //iterator begin() { return Data_.begin(); }
+ //iterator end() { return Data_.end(); }
+ //int* Ptr() { return &(Data_[0]); }
};
-// ----- INLINE FUNCTIONS ------------------------------------------------------
-void DataSet_integer::AddVal(size_t frame, int ival) {
- if (frame < Data_.size())
- Data_[frame] += ival;
- else {
- if (frame > Data_.size()) Data_.resize( frame, 0 );
- Data_.push_back( ival );
- }
-}
#endif
diff --git a/src/DataSet_integer_disk.cpp b/src/DataSet_integer_disk.cpp
new file mode 100644
index 0000000000..ea5df7a1ce
--- /dev/null
+++ b/src/DataSet_integer_disk.cpp
@@ -0,0 +1,173 @@
+#ifdef BINTRAJ
+#include
+#include "DataSet_integer_disk.h"
+#include "CpptrajStdio.h"
+#include "NC_Routines.h"
+#include "File_TempName.h"
+
+/// CONSTRUCTOR
+DataSet_integer_disk::DataSet_integer_disk() :
+ ncid_(-1),
+ framevid_(-1),
+ nvals_(0)
+{
+ start_[0] = 0;
+ count_[0] = 0;
+ // NOTE: Since tmpnam() use is considered dangerous, use the
+ // DataSetDiskCache name in its place.
+ tfname_ = File::GenTempName();
+ if (tfname_.empty()) {
+ mprinterr("Internal Error: Could not get temporary file name of dist integer data set.\n");
+ return;
+ }
+ if (NC::CheckErr( nc_create( tfname_.full(), NC_64BIT_OFFSET, &ncid_ ) )) {
+ mprinterr("Internal Error: Could not disk cache integer data set.\n");
+ }
+ //mprintf("DEBUG: Integer data set being cached in file: %s\n", tfname_.full());
+ int frameDID;
+ if (NC::CheckErr(nc_def_dim(ncid_, "frame", NC_UNLIMITED, &frameDID))) {
+ mprinterr("Internal Error: Could not define frame dimension for disk integer data set.\n");
+ }
+ int dimensionID[NC_MAX_VAR_DIMS];
+ dimensionID[0] = frameDID;
+ if (NC::CheckErr(nc_def_var(ncid_, "values", NC_INT, 1, dimensionID, &framevid_))) {
+ mprinterr("Internal Error: Could not define frame variable for disk integer data set.\n");
+ }
+ // End definitions
+ if (NC::CheckErr(nc_enddef(ncid_))) {
+ mprinterr("Internal Error: Ending definitions for disk integer data set.");
+ }
+}
+
+/// DESTRUCTOR
+DataSet_integer_disk::~DataSet_integer_disk() {
+ if (ncid_ != -1) nc_close( ncid_ );
+ if (!tfname_.empty()) File::FreeTempName( tfname_ );
+}
+
+#ifdef MPI
+// TODO
+int DataSet_integer_disk::Sync(size_t total, std::vector const& rank_frames,
+ Parallel::Comm const& commIn)
+{
+ if (commIn.Size() > 1) {
+ mprinterr("Internal Error: Data set sync for integer disk-cached data sets is not yet supported.\n");
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+// DataSet_integer_disk::Info()
+void DataSet_integer_disk::Info() const {
+ mprintf(" (cached)");
+}
+
+// DataSet_integer_disk::Allocate()
+int DataSet_integer_disk::Allocate(SizeArray const& sizeIn) {
+ return 0;
+}
+
+// DataSet_integer_disk::getVal()
+int DataSet_integer_disk::getVal(size_t idx) const {
+ size_t start[1], count[1];
+ start[0] = idx;
+ count[0] = 1;
+ int val;
+ nc_get_vara_int(ncid_, framevid_, start, count, &val);
+ return val;
+}
+
+// DataSet_integer_disk::setVal()
+void DataSet_integer_disk::setVal(size_t idx, int val) {
+ start_[0] = idx;
+ count_[0] = 1;
+ nc_put_vara_int(ncid_, framevid_, start_, count_, &val);
+ //nc_sync(ncid_);
+}
+
+// DataSet_integer_disk::Add()
+void DataSet_integer_disk::Add(size_t frame, const void* vIn) {
+ if (frame > nvals_)
+ Resize(frame);
+ start_[0] = nvals_;
+ count_[0] = 1;
+ nc_put_vara_int(ncid_, framevid_, start_, count_, (const int*)vIn);
+ //nc_sync(ncid_);
+ nvals_++;
+}
+
+// DataSet_integer_disk::WriteBuffer()
+void DataSet_integer_disk::WriteBuffer(CpptrajFile &cbuffer, SizeArray const& pIn) const {
+ if (pIn[0] >= nvals_)
+ cbuffer.Printf(format_.fmt(), 0);
+ else
+ cbuffer.Printf(format_.fmt(), getVal(pIn[0]));
+}
+
+// DataSet_integer_disk::Append()
+int DataSet_integer_disk::Append(DataSet* dsIn) {
+ if (dsIn->Empty()) return 0;
+ if (dsIn->Group() != SCALAR_1D) return 1;
+ DataSet_1D const& ds = static_cast( *dsIn );
+ for (unsigned int i = 0; i != ds.Size(); i++) {
+ int val =(int)ds.Dval(i);
+ Add(i, &val);
+ }
+ return 0;
+}
+
+// DataSet_integer_disk::Dval()
+double DataSet_integer_disk::Dval(size_t idx) const {
+ return (double)getVal(idx);
+}
+
+// DataSet_integer_disk::VoidPtr()
+const void* DataSet_integer_disk::VoidPtr(size_t offset) const {
+ mprinterr("Internal Error: VoidPtr() not implemented for DataSet_integer_disk.\n");
+ return 0;
+}
+
+// DataSet_integer_disk::SetElement()
+void DataSet_integer_disk::SetElement(size_t idx, int val) {
+ setVal(idx, val);
+}
+
+// DataSet_integer_disk::operator[]()
+int DataSet_integer_disk::operator[](size_t idx) const {
+ return getVal(idx);
+}
+
+// FIXME redundant
+void DataSet_integer_disk::AddElement(int val) {
+ Add(0, &val);
+}
+
+// DataSet_integer_disk::Resize()
+void DataSet_integer_disk::Resize(size_t sizeIn) {
+ if (sizeIn < nvals_)
+ nvals_ = sizeIn;
+ else if (sizeIn > nvals_) {
+ const int zero = 0;
+ for (size_t idx = nvals_; idx != sizeIn; idx++)
+ setVal(idx, zero);
+ nvals_ = sizeIn;
+ }
+}
+
+// DataSet_integer_disk::Assign()
+void DataSet_integer_disk::Assign(size_t sizeIn, int val) {
+ for (size_t idx = 0; idx != sizeIn; idx++)
+ setVal(idx, val);
+ nvals_ = sizeIn;
+}
+
+// DataSet_integer_disk::AddVal()
+void DataSet_integer_disk::AddVal(size_t idx, int val) {
+ if (idx < nvals_) {
+ int newval = getVal(idx) + val;
+ setVal(idx, newval);
+ } else
+ Add(idx, &val);
+}
+#endif /* BINTRAJ */
diff --git a/src/DataSet_integer_disk.h b/src/DataSet_integer_disk.h
new file mode 100644
index 0000000000..e111b12151
--- /dev/null
+++ b/src/DataSet_integer_disk.h
@@ -0,0 +1,50 @@
+#ifndef INC_DATASET_INTEGER_DISK_H
+#define INC_DATASET_INTEGER_DISK_H
+#ifdef BINTRAJ
+#include "DataSet_integer.h"
+/// Integer data set, cached to disk with NetCDF
+class DataSet_integer_disk : public DataSet_integer {
+ public:
+ DataSet_integer_disk();
+ ~DataSet_integer_disk();
+ static DataSet* Alloc() { return (DataSet*)new DataSet_integer_disk(); }
+ // ----- DataSet functions -------------------
+ size_t Size() const { return nvals_; }
+# ifdef MPI
+ int Sync(size_t, std::vector const&, Parallel::Comm const&);
+# endif
+ void Info() const;
+ int Allocate(SizeArray const&);
+ void Add( size_t, const void* );
+ void WriteBuffer(CpptrajFile&, SizeArray const&) const;
+ int Append(DataSet*);
+ size_t MemUsageInBytes() const { return 0; }
+ // ----- DataSet_1D functions ----------------
+ double Dval(size_t) const;
+ /// This function is invalid for DataSet_integer_disk
+ const void* VoidPtr(size_t) const;
+ // ----- DataSet_integer functions -----------
+ //int& operator[](size_t);
+ void SetElement(size_t, int);
+ int operator[](size_t) const;
+ void AddElement(int);
+ void Resize(size_t);
+ void Assign(size_t,int);
+ void AddVal(size_t, int);
+ //typedef std::vector::iterator iterator;
+ //iterator begin() { return Data_.begin(); }
+ //iterator end() { return Data_.end(); }
+ //int* Ptr() { return &(Data_[0]); }
+ private:
+ inline int getVal(size_t) const;
+ inline void setVal(size_t, int);
+
+ FileName tfname_;
+ int ncid_;
+ int framevid_;
+ size_t start_[1]; ///< Hold current index
+ size_t count_[1]; ///< Current size to read/write
+ unsigned int nvals_; ///< Total number of values in data set
+};
+#endif
+#endif
diff --git a/src/DataSet_integer.cpp b/src/DataSet_integer_mem.cpp
similarity index 51%
rename from src/DataSet_integer.cpp
rename to src/DataSet_integer_mem.cpp
index 167d630223..81f93aebe5 100644
--- a/src/DataSet_integer.cpp
+++ b/src/DataSet_integer_mem.cpp
@@ -1,16 +1,17 @@
-#include "DataSet_integer.h"
+#include "DataSet_integer_mem.h"
+//#inc lude "CpptrajStdio.h" // DEBUG
-// DataSet_integer::Allocate()
+// DataSet_integer_mem::Allocate()
/** Reserve space in the Data and Frames arrays. */
-int DataSet_integer::Allocate( SizeArray const& sizeIn ) {
+int DataSet_integer_mem::Allocate( SizeArray const& sizeIn ) {
if (!sizeIn.empty())
Data_.reserve( sizeIn[0] );
return 0;
}
-// DataSet_integer::Add()
+// DataSet_integer_mem::Add()
/** Insert data vIn at frame. */
-void DataSet_integer::Add(size_t frame, const void* vIn) {
+void DataSet_integer_mem::Add(size_t frame, const void* vIn) {
if (frame > Data_.size())
Data_.resize( frame, 0 );
// Always insert at the end
@@ -18,22 +19,22 @@ void DataSet_integer::Add(size_t frame, const void* vIn) {
Data_.push_back( *((int*)vIn) );
}
-// DataSet_integer::WriteBuffer()
+// DataSet_integer_mem::WriteBuffer()
/** Write data at frame to CharBuffer. If no data for frame write 0.0.
*/
-void DataSet_integer::WriteBuffer(CpptrajFile &cbuffer, SizeArray const& pIn) const {
+void DataSet_integer_mem::WriteBuffer(CpptrajFile &cbuffer, SizeArray const& pIn) const {
if (pIn[0] >= Data_.size())
cbuffer.Printf(format_.fmt(), 0);
else
cbuffer.Printf(format_.fmt(), Data_[pIn[0]]);
}
-int DataSet_integer::Append(DataSet* dsIn) {
+int DataSet_integer_mem::Append(DataSet* dsIn) {
if (dsIn->Empty()) return 0;
if (dsIn->Group() != SCALAR_1D) return 1;
- if (dsIn->Type() == INTEGER) {
+ if (dsIn->Type() == INTEGER) { // TODO check disk cache
size_t oldsize = Size();
- std::vector const& dataIn = ((DataSet_integer*)dsIn)->Data_;
+ std::vector const& dataIn = ((DataSet_integer_mem*)dsIn)->Data_;
Data_.resize( oldsize + dataIn.size() );
std::copy( dataIn.begin(), dataIn.end(), Data_.begin() + oldsize );
} else {
@@ -45,8 +46,8 @@ int DataSet_integer::Append(DataSet* dsIn) {
}
#ifdef MPI
-// DataSet_integer::Sync()
-int DataSet_integer::Sync(size_t total, std::vector const& rank_frames,
+// DataSet_integer_mem::Sync()
+int DataSet_integer_mem::Sync(size_t total, std::vector const& rank_frames,
Parallel::Comm const& commIn)
{
if (commIn.Size()==1) return 0;
@@ -63,4 +64,24 @@ int DataSet_integer::Sync(size_t total, std::vector const& rank_frames,
commIn.SendMaster( &(Data_[0]), Data_.size(), commIn.Rank(), MPI_INT );
return 0;
}
+
+/** Receive integer data from rank, append to after offset. */
+int DataSet_integer_mem::Recv(size_t total, unsigned int offset, int nframes,
+ int fromRank, int tag, Parallel::Comm const& commIn)
+{
+ Data_.resize( total );
+ int* d_beg = &(Data_[0]) + offset;
+ //rprintf("DEBUG: Receive %i frames fromRank %i tag %i\n", nframes, fromRank, tag);
+ if (commIn.Recv( d_beg, nframes, MPI_INT, fromRank, tag )) return 1;
+ // TODO Do SetNeedsSync false here?
+ return 0;
+}
+
+/** Send integer data to rank. */
+int DataSet_integer_mem::Send(int toRank, int tag, Parallel::Comm const& commIn)
+const
+{
+ //rprintf("DEBUG: Send %zu frames toRank %i tag %i\n", Data_.size(), toRank, tag);
+ return commIn.Send( (void*)&(Data_[0]), Data_.size(), MPI_INT, toRank, tag );
+}
#endif
diff --git a/src/DataSet_integer_mem.h b/src/DataSet_integer_mem.h
new file mode 100644
index 0000000000..ba2ecd484b
--- /dev/null
+++ b/src/DataSet_integer_mem.h
@@ -0,0 +1,52 @@
+#ifndef INC_DATASET_INTEGER_MEM_H
+#define INC_DATASET_INTEGER_MEM_H
+#include
+#include "DataSet_integer.h"
+/// Hold an array of integer values in memory.
+class DataSet_integer_mem : public DataSet_integer {
+ public:
+ DataSet_integer_mem() {}
+ static DataSet* Alloc() { return (DataSet*)new DataSet_integer_mem();}
+ // ----- DataSet_integer functions -----------
+ void SetElement(size_t idx, int val) { Data_[idx] = val; }
+ int operator[](size_t idx) const { return Data_[idx]; }
+ void AddElement(int i) { Data_.push_back( i ); }
+ /// Make set size sizeIn, all values set to 0.0.
+ void Resize(size_t sizeIn) { Data_.resize(sizeIn, 0); }
+ /// Make set size sizeIn, all values set to val.
+ void Assign(size_t sizeIn, int val) { Data_.resize(sizeIn, -1); }
+ inline void AddVal(size_t, int);
+ // ----- DataSet_1D functions ----------------
+ double Dval(size_t idx) const { return (double)Data_[idx]; }
+ const void* VoidPtr(size_t idx) const { return (void*)(&(Data_[0])+idx); }
+ // ----- DataSet functions -------------------
+ size_t Size() const { return Data_.size(); }
+# ifdef MPI
+ int Sync(size_t, std::vector const&, Parallel::Comm const&);
+ int Recv(size_t, unsigned int, int, int, int, Parallel::Comm const&);
+ int Send(int, int, Parallel::Comm const&) const;
+# endif
+ void Info() const { return; }
+ int Allocate(SizeArray const&);
+ void Add( size_t, const void* );
+ void WriteBuffer(CpptrajFile&, SizeArray const&) const;
+ int Append(DataSet*);
+ size_t MemUsageInBytes() const { return Data_.size() * sizeof(int); }
+ // -------------------------------------------
+ //typedef std::vector::iterator iterator;
+ //iterator begin() { return Data_.begin(); }
+ //iterator end() { return Data_.end(); }
+ //int* Ptr() { return &(Data_[0]); }
+ private:
+ std::vector Data_;
+};
+// ----- INLINE FUNCTIONS ------------------------------------------------------
+void DataSet_integer_mem::AddVal(size_t frame, int ival) {
+ if (frame < Data_.size())
+ Data_[frame] += ival;
+ else {
+ if (frame > Data_.size()) Data_.resize( frame, 0 );
+ Data_.push_back( ival );
+ }
+}
+#endif
diff --git a/src/DataSet_pH.cpp b/src/DataSet_pH.cpp
index 4ffbe39b08..ba30757f1a 100644
--- a/src/DataSet_pH.cpp
+++ b/src/DataSet_pH.cpp
@@ -14,6 +14,14 @@ int DataSet_pH::Allocate(SizeArray const& sizeIn) {
return 0;
}
+size_t DataSet_pH::MemUsageInBytes() const {
+ return sizeof(float) +
+ (res_.DataSize()) +
+ (states_.size() * sizeof(int)) +
+ (recType_.size() * sizeof(int)) +
+ time_.DataSize();
+}
+
void DataSet_pH::WriteBuffer(CpptrajFile &cbuffer, SizeArray const& pIn) const {
if (pIn[0] >= states_.size())
cbuffer.Printf(format_.fmt(), 0);
diff --git a/src/DataSet_pH.h b/src/DataSet_pH.h
index b532f60937..dd4f77076b 100644
--- a/src/DataSet_pH.h
+++ b/src/DataSet_pH.h
@@ -17,6 +17,7 @@ class DataSet_pH : public DataSet_1D {
int Allocate(SizeArray const&);
void Add( size_t, const void* ) { return; }
int Append(DataSet*) { return 1; }
+ size_t MemUsageInBytes() const;
# ifdef MPI
int Sync(size_t, std::vector const&, Parallel::Comm const&) { return 1; }
/// Sum data to the specified rank in communicator
diff --git a/src/DataSet_string.cpp b/src/DataSet_string.cpp
index ea8d069e02..a710279fbc 100644
--- a/src/DataSet_string.cpp
+++ b/src/DataSet_string.cpp
@@ -1,5 +1,13 @@
#include "DataSet_string.h"
+size_t DataSet_string::MemUsageInBytes() const {
+ size_t mySize = 0;
+ for (std::vector::const_iterator it = Data_.begin();
+ it != Data_.end(); ++it)
+ mySize += (it->size() * sizeof(char));
+ return mySize;
+}
+
// DataSet_string::Allocate()
/** Reserve space in the Data and Frames arrays. */
int DataSet_string::Allocate( SizeArray const& sizeIn ) {
diff --git a/src/DataSet_string.h b/src/DataSet_string.h
index 5789caa135..3f2cbd09ae 100644
--- a/src/DataSet_string.h
+++ b/src/DataSet_string.h
@@ -26,6 +26,7 @@ class DataSet_string : public DataSet {
void Add( size_t, const void* );
void WriteBuffer(CpptrajFile&, SizeArray const&) const;
int Append(DataSet*);
+ size_t MemUsageInBytes() const;
private:
std::vector Data_;
};
diff --git a/src/Exec_Commands.cpp b/src/Exec_Commands.cpp
index 7b9677b57c..4f57d388e1 100644
--- a/src/Exec_Commands.cpp
+++ b/src/Exec_Commands.cpp
@@ -153,3 +153,22 @@ Exec::RetType Exec_EnsFileExt::Execute(CpptrajState& State, ArgList& argIn) {
}
return CpptrajState::OK;
}
+// -----------------------------------------------------------------------------
+void Exec_UseDiskCache::Help() const {
+ mprintf("\t{on|off}\n"
+ " If on, CPPTRAJ will attempt to cache data sets to disk if possible.\n");
+}
+
+Exec::RetType Exec_UseDiskCache::Execute(CpptrajState& State, ArgList& argIn) {
+ if (argIn.hasKey("on")) {
+ State.DSL().SetDiskCache(true);
+ mprintf("\tWill attempt to cache data sets to disk if possible.\n");
+ } else if (argIn.hasKey("off")) {
+ State.DSL().SetDiskCache(false);
+ mprintf("\tData sets will be stored in memory.\n");
+ } else {
+ mprinterr("Error: Expect 'on' or 'off'\n");
+ return CpptrajState::ERR;
+ }
+ return CpptrajState::OK;
+}
diff --git a/src/Exec_Commands.h b/src/Exec_Commands.h
index 843fc5d6cf..4641b9d4b2 100644
--- a/src/Exec_Commands.h
+++ b/src/Exec_Commands.h
@@ -162,4 +162,13 @@ class Exec_EnsFileExt : public Exec {
DispatchObject* Alloc() const { return (DispatchObject*)new Exec_EnsFileExt(); }
RetType Execute(CpptrajState&, ArgList&);
};
+
+/// Enabled/disable caching of DataSets to disk.
+class Exec_UseDiskCache : public Exec {
+ public:
+ Exec_UseDiskCache() : Exec(GENERAL) {}
+ void Help() const;
+ DispatchObject* Alloc() const { return (DispatchObject*)new Exec_UseDiskCache(); }
+ RetType Execute(CpptrajState&, ArgList&);
+};
#endif
diff --git a/src/FileName.h b/src/FileName.h
index 36671e2a70..5a70641e75 100644
--- a/src/FileName.h
+++ b/src/FileName.h
@@ -10,6 +10,8 @@ class FileName {
FileName(const char* s) { SetFileName( std::string(s) ); }
FileName(const FileName&);
FileName& operator=(const FileName&);
+ /// \return true if full path matches
+ bool operator==(FileName const& rhs) const { return (fullPathName_ == rhs.fullPathName_); }
/// Set file name and extensions, perform expansion as necessary.
int SetFileName(std::string const&);
/// Set file name, no expansions.
diff --git a/src/File_TempName.cpp b/src/File_TempName.cpp
new file mode 100644
index 0000000000..d467d32b35
--- /dev/null
+++ b/src/File_TempName.cpp
@@ -0,0 +1,46 @@
+#include
+#include
+#include "File_TempName.h"
+#include "StringRoutines.h"
+#include "CpptrajStdio.h"
+
+namespace File {
+
+typedef std::list NameList;
+
+static NameList TempFileNames_ = NameList();
+
+// This seems a resonable limit for now
+static const unsigned int maxtmpidx_ = 1628634;
+
+static std::string TempPrefix_ = "cpptrajtmp";
+
+/** Generate a temporary file name of format:
+ * TempPrefix_<#>
+ * where <#> is based on the current number of temporary file names
+ * that have been requested.
+ */
+FileName GenTempName() {
+ // Could also set this to 0, but setting it to size is a better guarantee
+ // that the name will be free.
+ unsigned int tmpidx = TempFileNames_.size();
+ FileName temp( TempPrefix_ + integerToString(tmpidx) );
+ while (tmpidx < maxtmpidx_ && Exists(temp)) {
+ tmpidx++;
+ temp = FileName( TempPrefix_ + integerToString(tmpidx) );
+ }
+ if (tmpidx >= maxtmpidx_) {
+ mprinterr("Internal Error: Too many temporary files. Remove files named '%s*'\n",
+ TempPrefix_.c_str());
+ return FileName();
+ }
+ return temp;
+}
+
+/** Free the given temporary file name. */
+void FreeTempName(FileName const& temp) {
+ TempFileNames_.remove( temp );
+ if (Exists(temp)) remove(temp.full());
+}
+
+} /* END namespace File */
diff --git a/src/File_TempName.h b/src/File_TempName.h
new file mode 100644
index 0000000000..dbe50bd97a
--- /dev/null
+++ b/src/File_TempName.h
@@ -0,0 +1,10 @@
+#ifndef FILE_TEMPNAME_H
+#define FILE_TEMPNAME_H
+#include "FileName.h"
+namespace File {
+ /// \return A temporary file name.
+ FileName GenTempName();
+ /// Indicate temporary file name no longer needed.
+ void FreeTempName(FileName const&);
+} /* END namespace File */
+#endif
diff --git a/src/Frame.cpp b/src/Frame.cpp
index bf3e3fa33a..23c0e413f3 100644
--- a/src/Frame.cpp
+++ b/src/Frame.cpp
@@ -322,6 +322,22 @@ Frame::CRDtype Frame::ConvertToCRD(int numBoxCrd, bool hasVel) const {
}
// ---------- ACCESS INTERNAL DATA ---------------------------------------------
+// Frame::DataSize()
+/** Size of Frame in memory. */
+size_t Frame::DataSize() const {
+ size_t mySize = (5 * sizeof(int)) +
+ (10 * sizeof(double)) + // box + class vars
+ (remd_indices_.size() * sizeof(int)) +
+ (Mass_.size() * sizeof(double));
+ if (!memIsExternal_ && X_ != 0)
+ mySize += (maxnatom_ * 3 * sizeof(double));
+ if (V_ != 0)
+ mySize += (maxnatom_ * 3 * sizeof(double));
+ if (F_ != 0)
+ mySize += (maxnatom_ * 3 * sizeof(double));
+ return mySize;
+}
+
// Frame::printAtomCoord()
void Frame::printAtomCoord(int atom) const {
int atmidx = atom * 3;
diff --git a/src/Frame.h b/src/Frame.h
index d3fb30659e..50f222a33e 100644
--- a/src/Frame.h
+++ b/src/Frame.h
@@ -55,6 +55,8 @@ class Frame {
/// Convert this frame to CRDtype.
CRDtype ConvertToCRD(int, bool) const;
// -------------------------------------------
+ /// \return Size of Frame in memory
+ size_t DataSize() const;
/// Print XYZ coordinates for given atom.
void printAtomCoord(int) const;
/// Print information about the frame.
diff --git a/src/Grid.h b/src/Grid.h
index bddc5ed39b..c2cff2bea6 100644
--- a/src/Grid.h
+++ b/src/Grid.h
@@ -47,6 +47,10 @@ template class Grid {
typedef ArrayIterator iterator;
iterator begin() { return grid_; }
iterator end() { return grid_ + nelements_; }
+ /// \return memory usage in bytes
+ size_t DataSize() const {
+ return ( (4*sizeof(size_t)) + (nelements_ * sizeof(T)) );
+ }
private:
size_t nx_; ///< Grid X dimension.
size_t ny_; ///< Grid Y dimension.
diff --git a/src/NameType.h b/src/NameType.h
index 7e5652c601..bec8e0df99 100644
--- a/src/NameType.h
+++ b/src/NameType.h
@@ -44,6 +44,7 @@ class NameType {
}
return false;
}
+ static size_t DataSize() { return NameSize_ * sizeof(char); }
private:
char c_array_[NameSize_];
diff --git a/src/ParameterHolders.h b/src/ParameterHolders.h
index e69ec1622a..bef4e1a254 100644
--- a/src/ParameterHolders.h
+++ b/src/ParameterHolders.h
@@ -48,6 +48,8 @@ class AtomTypeHolder {
}
return match;
}
+ /// \return size used in memory
+ size_t DataSize() const { return types_.size() * NameType::DataSize(); }
/*
/// The lowest type name of either end is used for sorting.
bool operator<(AtomTypeHolder const& rhs) const {
@@ -119,6 +121,15 @@ template class ParmHolder {
typedef typename Bmap::const_iterator const_iterator;
const_iterator begin() const { return bpmap_.begin(); }
const_iterator end() const { return bpmap_.end(); }
+
+ size_t DataSize() const {
+ if (bpmap_.empty()) return 0;
+ const_iterator elt0 = begin();
+ // Assume all AtomTypeHolders are the same size
+ return (bpmap_.size() * elt0->first.DataSize()) +
+ (bpmap_.size() * sizeof(T)) +
+ sizeof(Bmap);
+ }
private:
Bmap bpmap_;
};
diff --git a/src/ReplicaDimArray.h b/src/ReplicaDimArray.h
index bcccab2271..bea81a188a 100644
--- a/src/ReplicaDimArray.h
+++ b/src/ReplicaDimArray.h
@@ -51,6 +51,7 @@ class ReplicaDimArray {
void assign( unsigned int n, RemDimType t ) { remDims_.assign(n, t); }
int* Ptr() { return (int*)&remDims_[0]; }
# endif
+ size_t DataSize() const { return remDims_.size() * sizeof(RemDimType); }
private:
std::vector remDims_;
};
diff --git a/src/SpaceGroup.cpp b/src/SpaceGroup.cpp
index 15d3efd014..1e434a0b8c 100644
--- a/src/SpaceGroup.cpp
+++ b/src/SpaceGroup.cpp
@@ -1,4 +1,6 @@
#include "SpaceGroup.h"
+#include "Matrix_3x3.h"
+#include "Vec3.h"
/// CONSTRUCTOR
SpaceGroup::SpaceGroup() :
diff --git a/src/SpaceGroup.h b/src/SpaceGroup.h
index 436ced5b0d..eaf7e6d124 100644
--- a/src/SpaceGroup.h
+++ b/src/SpaceGroup.h
@@ -3,8 +3,9 @@
#include
#include
#include