00001 #include "qsescan.h"
00002 #include "qsedataset.h"
00003
00004 #include <QRegExp>
00005
00006 #include <math.h>
00007
00008 QseScan::QseScan(const char *name)
00009 : QObject(NULL),
00010
00011 m_Name(name),
00012 m_Command(name),
00013 m_Mutex(QMutex::Recursive),
00014 m_ScanDateTime(QDateTime::currentDateTime()),
00015 m_ScanNumber(-1)
00016 {
00017 }
00018
00019 QseScan::~QseScan()
00020 {
00021 QMutexLocker lock(&m_Mutex);
00022
00023 QseColumn *column;
00024
00025 foreach (column, m_Columns) {
00026 delete column;
00027 }
00028 }
00029
00030 QString QseScan::name() const
00031 {
00032 QMutexLocker lock(&m_Mutex);
00033
00034 return m_Name;
00035 }
00036
00037 void QseScan::setName(QString name)
00038 {
00039 QMutexLocker lock(&m_Mutex);
00040
00041 m_Name = name;
00042 }
00043
00044 int QseScan::columnCount() const
00045 {
00046 QMutexLocker lock(&m_Mutex);
00047
00048 return m_Columns.size();
00049 }
00050
00051 void QseScan::setColumnCount(int n)
00052 {
00053 int sz = columnCount();
00054
00055 for (int i = sz-1; i>=n; i--) {
00056 QMutexLocker lock(&m_Mutex);
00057
00058 if (m_Columns[i]) {
00059 delete m_Columns.takeAt(i);
00060 }
00061 }
00062 }
00063
00064 void QseScan::clear()
00065 {
00066 setColumnCount(0);
00067
00068 QMutexLocker lock(&m_Mutex);
00069
00070 m_Header.clear();
00071 }
00072
00073 int QseScan::maxRowCount() const
00074 {
00075 int maxcount = 0;
00076 int nc = columnCount();
00077
00078 for (int i=0; i<nc; i++) {
00079 QseColumn *c = column(i);
00080
00081 if (c) {
00082 int nr = c->rowCount();
00083
00084 if (nr > maxcount) {
00085 maxcount = nr;
00086 }
00087 }
00088 }
00089
00090 return maxcount;
00091 }
00092
00093 void QseScan::setRowCount(int n)
00094 {
00095 QMutexLocker lock(&m_Mutex);
00096 QseColumn *column;
00097
00098 foreach (column, m_Columns) {
00099 column -> setRowCount(n);
00100 }
00101 }
00102
00103 QseColumn* QseScan::column(int n) const
00104 {
00105 if ((0 <= n) && (n < m_Columns.size())) {
00106 return m_Columns.at(n);
00107 } else {
00108 return NULL;
00109 }
00110 }
00111
00112 QseColumn* QseScan::column(const QString& nm) const
00113 {
00114 QMutexLocker lock(&m_Mutex);
00115 QseColumn *column;
00116
00117 foreach (column, m_Columns) {
00118 if (column && (column->name()==nm)) {
00119 return column;
00120 }
00121 }
00122
00123 return NULL;
00124 }
00125
00126 void QseScan::setColumnNames(const char *nms)
00127 {
00128 const char *ptr = nms + 3;
00129 const char *found, *next;
00130 int nc = columnCount();
00131 int col;
00132 char nam[256];
00133
00134 for (col = 0; ptr; col++) {
00135 while ((*ptr)=='\t' || (*ptr)==' ') {
00136 ptr++;
00137 }
00138
00139 found = strstr(ptr, " ");
00140 if (found) {
00141 next = found + 2;
00142 } else {
00143 next = NULL;
00144 }
00145
00146 QseColumn* c= NULL;
00147
00148 if (next) {
00149 qstrncpy(nam, ptr, found-ptr+1);
00150 c = appendColumn(nam);
00151 } else {
00152 c = appendColumn(ptr);
00153 }
00154
00155 nc++;
00156 ptr = next;
00157 }
00158 }
00159
00160 void QseScan::appendHeader(const QString& h)
00161 {
00162 QMutexLocker lock(&m_Mutex);
00163 m_Header.push_back(h);
00164 }
00165
00166 QStringList QseScan::header() const
00167 {
00168 QMutexLocker lock(&m_Mutex);
00169 return m_Header;
00170 }
00171
00172 void QseScan::mergeHeaders(const QStringList &hdr)
00173 {
00174 QString hdrline;
00175
00176 foreach (hdrline, hdr) {
00177 bool nocont;
00178 {
00179 QMutexLocker lock(&m_Mutex);
00180 nocont = !m_Header.contains(hdrline);
00181 }
00182
00183 if (nocont) {
00184 appendHeader(hdrline);
00185 }
00186 }
00187 }
00188
00189 void QseScan::appendData(const char *l)
00190 {
00191 int nc = columnCount();
00192 const char *ptr = l;
00193 char *next;
00194
00195 for (int col = 0; ptr; col++) {
00196 double val;
00197 val = strtod(ptr, &next);
00198
00199 if (ptr == next) {
00200 return ;
00201 }
00202
00203 QseColumn *c=NULL;
00204
00205 if (col >= nc) {
00206 c = appendColumn(QString("col%1").arg(col));
00207
00208 if (nc > 0) {
00209 c -> setRowCount(column(0)->rowCount() - 1);
00210 }
00211
00212 nc++;
00213 } else {
00214 c = column(col);
00215 }
00216
00217 c -> appendData(val);
00218
00219 ptr = next;
00220 }
00221
00222 printf("\n");
00223 }
00224
00225 QString QseScan::scanCommand() const
00226 {
00227 QMutexLocker lock(&m_Mutex);
00228
00229 return m_Command;
00230 }
00231
00232 void QseScan::setScanCommand(const QString& cmd)
00233 {
00234 QMutexLocker lock(&m_Mutex);
00235
00236 m_Command = cmd;
00237 }
00238
00239 QseColumn *QseScan::appendColumn(const QString &name, const QseColumn *proto)
00240 {
00241 QseColumn *res=NULL;
00242
00243 {
00244 QMutexLocker lock(&m_Mutex);
00245
00246 res = new QseColumn(name);
00247 m_Columns.append(res);
00248 m_ColumnsDictionary[name]=res;
00249 }
00250
00251 if (proto) {
00252 res -> setRowCount(proto -> rowCount());
00253 res -> assignment(proto);
00254 } else if (columnCount() > 0) {
00255 res -> setRowCount(column(0)->rowCount());
00256 res -> assignment(0.0);
00257 }
00258
00259 return res;
00260 }
00261
00262 void QseScan::writeScan(const QString &name)
00263 {
00264 FILE *f = fopen(qPrintable(name),"w");
00265 int nr = maxRowCount();
00266 int nc = columnCount();
00267 int hsz;
00268
00269 {
00270 QMutexLocker lock(&m_Mutex);
00271 hsz = m_Header.size();
00272 }
00273
00274 for (int i = 0; i < hsz; i++) {
00275 QMutexLocker lock(&m_Mutex);
00276 fputs(qPrintable(m_Header[i]+"\n"), f);
00277 }
00278
00279 fprintf(f,"#N");
00280
00281 for (int i = 0; i < nc; i++) {
00282 QseColumn *c = column(i);
00283 if (c) {
00284 fprintf(f,"\t%s", qPrintable(c->name()));
00285 }
00286 }
00287
00288 fprintf(f,"\n");
00289
00290 for (int r = 0; r<nr; r++) {
00291 fprintf(f, "%d", r);
00292
00293 for (int i = 0; i < nc; i++) {
00294 QseColumn *c = column(i);
00295 if (c) {
00296 fprintf(f,"\t%0.12g", c->data(r));
00297 }
00298 }
00299
00300 fprintf(f,"\n");
00301 }
00302
00303 fclose(f);
00304 }
00305
00306 QDateTime QseScan::scanDateTime() const
00307 {
00308 QMutexLocker lock(&m_Mutex);
00309
00310 return m_ScanDateTime;
00311 }
00312
00313 void QseScan::setScanDateTime(const QDateTime& datetime)
00314 {
00315 QMutexLocker lock(&m_Mutex);
00316
00317 m_ScanDateTime = datetime;
00318 }
00319
00320 QString QseScan::scanDateLine() const
00321 {
00322 QMutexLocker lock(&m_Mutex);
00323
00324 return "#D " + m_ScanDateTime.toString(Qt::TextDate);
00325 }
00326
00327 QString QseScan::scanColumnCountLine() const
00328 {
00329 QMutexLocker lock(&m_Mutex);
00330
00331 return QString("#N %1").arg(columnCount());
00332 }
00333
00334 QString QseScan::scanColumnNamesLine() const
00335 {
00336 QMutexLocker lock(&m_Mutex);
00337
00338 QString res = "#L ";
00339 int ncols = columnCount();
00340
00341 for (int i=0; i<ncols; i++) {
00342 if (i != 0) {
00343 res += " ";
00344 }
00345
00346 res += column(i) -> name();
00347 }
00348
00349 return res;
00350 }
00351
00352 int QseScan::scanNumber() const
00353 {
00354 QMutexLocker lock(&m_Mutex);
00355
00356 return m_ScanNumber;
00357 }
00358
00359 void QseScan::setScanNumber(int n)
00360 {
00361 QMutexLocker lock(&m_Mutex);
00362
00363 m_ScanNumber = n;
00364 }
00365