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