1 /*****************************************************************************
5 ** Purpose: plotfile class
6 ** Programmer: Kevin Rosenberg
7 ** Date Started: Dec 2000
9 ** This is part of the CTSim program
10 ** Copyright (c) 1983-2009 Kevin Rosenberg
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License (version 2) as
14 ** published by the Free Software Foundation.
16 ** This program is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ** GNU General Public License for more details.
21 ** You should have received a copy of the GNU General Public License
22 ** along with this program; if not, write to the Free Software
23 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ******************************************************************************/
30 ///////////////////////////////////////////////////////////////////////////
31 // CLASS IMPLEMENTATION
34 // Purpose: Plot File storage
35 ///////////////////////////////////////////////////////////////////////////
38 PlotFile::PlotFile (int nCurves, int nRecords)
41 setCurveSize (nCurves, nRecords);
49 PlotFile::~PlotFile ()
54 PlotFile::initHeaders ()
58 time_t currentTime = time (NULL);
59 m_strDate = ctime (¤tTime);
60 m_vecStrDescriptions.clear();
61 m_vecStrEzsetCommands.clear();
65 PlotFile::setCurveSize (int nCols, int nRecords, bool bScatterPlot)
67 m_iNumColumns = nCols;
68 m_iNumRecords = nRecords;
69 m_bScatterPlot = bScatterPlot;
71 m_vecCurves.reserve (m_iNumColumns * m_iNumRecords);
75 // a Column's records are stored sequentially. It begins at iCol * m_iNumRecords
77 PlotFile::addColumn (int iCol, const double* const pdColData)
79 if (iCol < 0 || iCol >= m_iNumColumns) {
80 sys_error (ERR_SEVERE, "Illegal column number %d [PlotFile::addColumn]", iCol);
84 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
85 m_vecCurves[ iRec + (iCol * m_iNumRecords) ] = pdColData [iRec];
87 sys_error (ERR_TRACE, "Storing m_vecCurves[%d] = %f",
88 iRec + (iCol * m_iNumRecords),
96 PlotFile::addColumn (int iCol, const float* const pdColData)
98 if (iCol < 0 || iCol >= m_iNumColumns) {
99 sys_error (ERR_SEVERE, "Illegal column number %d [PlotFile::addColumn]", iCol);
103 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
104 m_vecCurves[ iRec + (iCol * m_iNumRecords) ] = pdColData [iRec];
110 PlotFile::getColumn (int iCol, double* pdColData) const
112 if (iCol < 0 || iCol >= m_iNumColumns) {
113 sys_error (ERR_SEVERE, "Illegal column number %d [PlotFile::addColumn]", iCol);
117 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
118 pdColData[iRec] = m_vecCurves[ iRec + (iCol * m_iNumRecords) ];
123 PlotFile::getMinMax (int iStartingCol, double& dMin, double& dMax) const
125 if (iStartingCol >= m_iNumColumns) {
126 sys_error (ERR_WARNING, "iStartingCol >= iNumColumns");
130 int iOffset = iStartingCol * m_iNumRecords;
131 dMin = m_vecCurves[ 0 + iOffset ];
134 for (int iCol = iStartingCol; iCol < m_iNumColumns; iCol++) {
135 int iOffset = iCol * m_iNumRecords;
136 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
137 double dVal = m_vecCurves[ iRec + iOffset ];
140 else if (dVal > dMax)
145 // sys_error (ERR_TRACE, "dMin=%f, dMax=%f", dMin, dMax);
150 PlotFile::statistics (int iStartingCol, double& min, double& max, double& mean, double& mode, double& median, double &stddev) const
152 if (iStartingCol >= m_iNumColumns) {
153 sys_error (ERR_WARNING, "iStartingCol >= iNumColumns");
157 int iNPoints = (m_iNumColumns - iStartingCol) * m_iNumRecords;
158 std::vector<double> vec;
159 vec.resize (iNPoints);
162 for (int iCol = iStartingCol; iCol < m_iNumColumns; iCol++) {
163 int iOffset = iCol * m_iNumRecords;
164 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
165 vec[iVec++] = m_vecCurves[ iRec + iOffset ];
168 vectorNumericStatistics (vec, iNPoints, min, max, mean, mode, median, stddev);
174 PlotFile::fileWrite (const char* const filename)
176 m_strFilename = filename;
178 fstream fs (m_strFilename.c_str(), std::ios::out | std::ios::trunc);
180 sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", m_strFilename.c_str());
184 if (! headerWrite(fs) || ! columnsWrite (fs))
191 PlotFile::fileRead (const char* const filename)
193 m_strFilename = filename;
196 fstream fs (m_strFilename.c_str(), std::ios::in);
198 fstream fs (m_strFilename.c_str(), std::ios::in); // | std::ios::nocreate);
202 sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", m_strFilename.c_str());
206 if (! headerRead(fs))
209 setCurveSize (m_iNumColumns, m_iNumRecords);
211 if (! columnsRead(fs))
218 PlotFile::headerRead (std::iostream& fs)
221 sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
227 bool bFinishedHeaders = false;
232 if (fs.fail() || m_iNumColumns == 0 || m_iNumRecords == 0)
235 while (! bFinishedHeaders && ! fs.eof() && ! fs.fail()) {
237 fs.getline (line, sizeof(line));
239 while (line[iSP] == ' ')
241 if (line[iSP] == '\n' || ! line[iSP])
243 else if (line[iSP] == '#') {
245 while (line[iSP] == ' ')
247 if (line[iSP] == '\n' || ! line[iSP])
250 addDescription (&line[iSP]);
251 } else if (strstr (&line[iSP], "<datapoints>") != NULL) {
252 bFinishedHeaders = true;
254 addEzsetCommand (&line[iSP]);
262 PlotFile::headerWrite (std::iostream& fs)
265 sys_error (ERR_WARNING, "Tried to write header with ! fs");
270 fs << m_iNumColumns << " " << m_iNumRecords << "\n";
273 for (i = 0; i < m_vecStrEzsetCommands.size(); i++)
274 fs << m_vecStrEzsetCommands[i] << "\n";
276 for (i = 0; i < m_vecStrDescriptions.size(); i++)
277 fs << "# " << m_vecStrDescriptions[i] << "\n";
279 if (! m_strDate.empty())
280 fs << "# Date: " << m_strDate << "\n";
287 PlotFile::columnsWrite (std::iostream& fs)
290 sys_error (ERR_WARNING, "Tried to columnWrite with !fs");
294 fs << "<datapoints>\n";
296 int iStride = m_iNumRecords;
297 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
298 for (int iCol = 0; iCol < m_iNumColumns; iCol++)
299 fs << m_vecCurves [iRec + (iCol * iStride)] << " ";
303 fs << "</datapoints>\n";
305 fs << "</plotfile>\n";
312 PlotFile::columnsRead (std::iostream& fs)
315 sys_error (ERR_WARNING, "Tried to arrayDataRead with ! fs");
319 if (m_iNumColumns == 0 || m_iNumRecords == 0) {
320 sys_error (ERR_WARNING, "Called PlotFile::columnsRead with 0 columns or records");
324 bool bTerminateEarly = false;
325 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
326 for (int iCol = 0; iCol < m_iNumColumns; iCol++) {
328 bTerminateEarly = true;
335 m_vecCurves[ iRec + (iCol * m_iNumRecords) ] = d;
339 return ! (bTerminateEarly || fs.fail());
344 PlotFile::printHeaders (std::ostream& os) const
346 os << "EZSet Commands\n";
347 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
348 os << m_vecStrEzsetCommands[iEZ] << "\n";
350 os << "Descriptions\n";
351 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
352 os << m_vecStrDescriptions[iDesc] << "\n";
356 PlotFile::printHeaders (std::ostringstream& os) const
358 os << "EZSet Commands\n";
359 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
360 os << m_vecStrEzsetCommands[iEZ] << "\n";
362 os << "Descriptions\n";
363 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
364 os << m_vecStrDescriptions[iDesc] << "\n";
368 PlotFile::printHeadersBrief (std::ostream& os) const
370 os << "EZSet Commands\n";
371 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
372 os << m_vecStrEzsetCommands[iEZ] << "; ";
373 if (m_vecStrEzsetCommands.size() > 0)
376 os << "Descriptions\n";
377 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
378 os << m_vecStrDescriptions[iDesc] << "\n";
382 PlotFile::printHeadersBrief (std::ostringstream& os) const
384 os << "EZSet Commands\n";
385 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
386 os << m_vecStrEzsetCommands[iEZ] << "; ";
387 if (m_vecStrEzsetCommands.size() > 0)
390 os << "Descriptions\n";
391 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
392 os << m_vecStrDescriptions[iDesc] << "\n";