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-2001 Kevin Rosenberg
14 ** This program is free software; you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License (version 2) as
16 ** published by the Free Software Foundation.
18 ** This program is distributed in the hope that it will be useful,
19 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ** GNU General Public License for more details.
23 ** You should have received a copy of the GNU General Public License
24 ** along with this program; if not, write to the Free Software
25 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 ******************************************************************************/
32 ///////////////////////////////////////////////////////////////////////////
33 // CLASS IMPLEMENTATION
36 // Purpose: Plot File storage
37 ///////////////////////////////////////////////////////////////////////////
40 PlotFile::PlotFile (int nCurves, int nRecords)
43 setCurveSize (nCurves, nRecords);
51 PlotFile::~PlotFile ()
56 PlotFile::initHeaders ()
60 time_t currentTime = time (NULL);
61 m_strDate = ctime (¤tTime);
62 m_vecStrDescriptions.clear();
63 m_vecStrEzsetCommands.clear();
67 PlotFile::setCurveSize (int nCols, int nRecords, bool bScatterPlot)
69 m_iNumColumns = nCols;
70 m_iNumRecords = nRecords;
71 m_bScatterPlot = bScatterPlot;
73 m_vecCurves.reserve (m_iNumColumns * m_iNumRecords);
77 // a Column's records are stored sequentially. It begins at iCol * m_iNumRecords
79 PlotFile::addColumn (int iCol, const double* const pdColData)
81 if (iCol < 0 || iCol >= m_iNumColumns) {
82 sys_error (ERR_SEVERE, "Illegal column number %d [PlotFile::addColumn]", iCol);
86 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
87 m_vecCurves[ iRec + (iCol * m_iNumRecords) ] = pdColData [iRec];
93 PlotFile::addColumn (int iCol, const float* const pdColData)
95 if (iCol < 0 || iCol >= m_iNumColumns) {
96 sys_error (ERR_SEVERE, "Illegal column number %d [PlotFile::addColumn]", iCol);
100 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
101 m_vecCurves[ iRec + (iCol * m_iNumRecords) ] = pdColData [iRec];
107 PlotFile::getColumn (int iCol, double* pdColData) const
109 if (iCol < 0 || iCol >= m_iNumColumns) {
110 sys_error (ERR_SEVERE, "Illegal column number %d [PlotFile::addColumn]", iCol);
114 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
115 pdColData[iRec] = m_vecCurves[ iRec + (iCol * m_iNumRecords) ];
120 PlotFile::getMinMax (int iStartingCol, double& dMin, double& dMax) const
122 if (iStartingCol >= m_iNumColumns) {
123 sys_error (ERR_WARNING, "iStartingCol >= iNumColumns");
127 int iOffset = iStartingCol * m_iNumRecords;
128 dMin = m_vecCurves[ 0 + iOffset ];
131 for (int iCol = iStartingCol; iCol < m_iNumColumns; iCol++) {
132 int iOffset = iCol * m_iNumRecords;
133 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
134 double dVal = m_vecCurves[ iRec + iOffset ];
137 else if (dVal > dMax)
146 PlotFile::statistics (int iStartingCol, double& min, double& max, double& mean, double& mode, double& median, double &stddev) const
148 if (iStartingCol >= m_iNumColumns) {
149 sys_error (ERR_WARNING, "iStartingCol >= iNumColumns");
153 int iNPoints = (m_iNumColumns - iStartingCol) * m_iNumRecords;
154 std::vector<double> vec;
155 vec.resize (iNPoints);
158 for (int iCol = iStartingCol; iCol < m_iNumColumns; iCol++) {
159 int iOffset = iCol * m_iNumRecords;
160 for (int iRec = 0; iRec < m_iNumRecords; iRec++)
161 vec[iVec++] = m_vecCurves[ iRec + iOffset ];
164 vectorNumericStatistics (vec, iNPoints, min, max, mean, mode, median, stddev);
170 PlotFile::fileWrite (const char* const filename)
172 m_strFilename = filename;
174 fstream fs (m_strFilename.c_str(), std::ios::out | std::ios::trunc);
176 sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", m_strFilename.c_str());
180 if (! headerWrite(fs) || ! columnsWrite (fs))
187 PlotFile::fileRead (const char* const filename)
189 m_strFilename = filename;
192 fstream fs (m_strFilename.c_str(), std::ios::in);
194 fstream fs (m_strFilename.c_str(), std::ios::in); // | std::ios::nocreate);
198 sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", m_strFilename.c_str());
202 if (! headerRead(fs))
205 setCurveSize (m_iNumColumns, m_iNumRecords);
207 if (! columnsRead(fs))
214 PlotFile::headerRead (std::iostream& fs)
217 sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
223 bool bFinishedHeaders = false;
228 if (fs.fail() || m_iNumColumns == 0 || m_iNumRecords == 0)
231 while (! bFinishedHeaders && ! fs.eof() && ! fs.fail()) {
233 fs.getline (line, sizeof(line));
235 while (line[iSP] == ' ')
237 if (line[iSP] == '\n' || ! line[iSP])
239 else if (line[iSP] == '#') {
241 while (line[iSP] == ' ')
243 if (line[iSP] == '\n' || ! line[iSP])
246 addDescription (&line[iSP]);
247 } else if (strstr (&line[iSP], "<datapoints>") != NULL) {
248 bFinishedHeaders = true;
250 addEzsetCommand (&line[iSP]);
258 PlotFile::headerWrite (std::iostream& fs)
261 sys_error (ERR_WARNING, "Tried to write header with ! fs");
266 fs << m_iNumColumns << " " << m_iNumRecords << "\n";
269 for (i = 0; i < m_vecStrEzsetCommands.size(); i++)
270 fs << m_vecStrEzsetCommands[i] << "\n";
272 for (i = 0; i < m_vecStrDescriptions.size(); i++)
273 fs << "# " << m_vecStrDescriptions[i] << "\n";
275 if (! m_strDate.empty())
276 fs << "# Date: " << m_strDate << "\n";
283 PlotFile::columnsWrite (std::iostream& fs)
286 sys_error (ERR_WARNING, "Tried to columnWrite with !fs");
290 fs << "<datapoints>\n";
292 int iStride = m_iNumRecords;
293 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
294 for (int iCol = 0; iCol < m_iNumColumns; iCol++)
295 fs << m_vecCurves [iRec + (iCol * iStride)] << " ";
299 fs << "</datapoints>\n";
301 fs << "</plotfile>\n";
308 PlotFile::columnsRead (std::iostream& fs)
311 sys_error (ERR_WARNING, "Tried to arrayDataRead with ! fs");
315 if (m_iNumColumns == 0 || m_iNumRecords == 0) {
316 sys_error (ERR_WARNING, "Called PlotFile::columnsRead with 0 columns or records");
320 bool bTerminateEarly = false;
321 for (int iRec = 0; iRec < m_iNumRecords; iRec++) {
322 for (int iCol = 0; iCol < m_iNumColumns; iCol++) {
324 bTerminateEarly = true;
331 m_vecCurves[ iRec + (iCol * m_iNumRecords) ] = d;
335 return ! (bTerminateEarly || fs.fail());
340 PlotFile::printHeaders (std::ostream& os) const
342 os << "EZSet Commands\n";
343 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
344 os << m_vecStrEzsetCommands[iEZ] << "\n";
346 os << "Descriptions\n";
347 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
348 os << m_vecStrDescriptions[iDesc] << "\n";
352 PlotFile::printHeaders (std::ostringstream& os) const
354 os << "EZSet Commands\n";
355 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
356 os << m_vecStrEzsetCommands[iEZ] << "\n";
358 os << "Descriptions\n";
359 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
360 os << m_vecStrDescriptions[iDesc] << "\n";
364 PlotFile::printHeadersBrief (std::ostream& os) const
366 os << "EZSet Commands\n";
367 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
368 os << m_vecStrEzsetCommands[iEZ] << "; ";
369 if (m_vecStrEzsetCommands.size() > 0)
372 os << "Descriptions\n";
373 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
374 os << m_vecStrDescriptions[iDesc] << "\n";
378 PlotFile::printHeadersBrief (std::ostringstream& os) const
380 os << "EZSet Commands\n";
381 for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)
382 os << m_vecStrEzsetCommands[iEZ] << "; ";
383 if (m_vecStrEzsetCommands.size() > 0)
386 os << "Descriptions\n";
387 for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)
388 os << m_vecStrDescriptions[iDesc] << "\n";