#include "export.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "seaset.h" #include "sicsconn.h" #include #include void Export::addRow(QString label, QWidget *widget, QString tip) { QLabel *labelW; if (label != "") { labelW = new QLabel(label, this); lay->addWidget(labelW, row, 0); if (tip != "") { QToolTip::add(labelW, tip); } } lay->addWidget(widget, row, 1); if (tip != "") { QToolTip::add(widget, tip); } row++; } Export::Export(SeaSet *setArg, QWidget *parent, const char *instr) : QWidget(parent) { QPushButton *ok, *cancel; char wd[PATH_MAX]; set = setArg; row = 0; instrument = instr; lay = new QGridLayout(this, 1, 3, 3, -1, "exportLayout"); lay->setColStretch(2,1); addRow("export: ", new QLabel("all active curves", this), ""); lay->addWidget(new QLabel("step [sec]", this), 1, 0); stepLE = new QLineEdit(this); QValidator* validator = new QIntValidator( 1, 24*3600, this ); stepLE->setValidator(validator); stepLE->setText("auto"); stepLE->setAlignment(Qt::AlignRight); stepLE->setFixedWidth(100); addRow("step [sec]", stepLE, "time step [sec] (auto: 5 sec or more, max. 1000 points)" ); scaleLE = new QLineEdit(this); scaleLE->setText("1"); scaleLE->setAlignment(Qt::AlignRight); scaleLE->setFixedWidth(100); addRow("x-scale [sec]", scaleLE, "enter 60 for minutes / 3600 for hours"); noneLE = new QLineEdit(this); noneLE->setText("NaN"); noneLE->setFixedWidth(100); addRow("none value", noneLE, "value to be used for undefined numbers"); filePath = getcwd(wd, sizeof wd); filePath.append("/seaexport.dat"); cancel = new QPushButton("Quit", this); lay->addWidget(cancel, row, 0); connect(cancel, SIGNAL(clicked()), this, SIGNAL(finish())); ok = new QPushButton("Export", this); lay->addWidget(ok, 5, 1); ok->setDefault(true); ok->setFixedWidth(100); addRow("", ok, ""); connect(ok, SIGNAL(clicked()), this, SLOT(exportXY())); message = new QLabel("", this); lay->addWidget(message, row, 1); row++; lay->setRowStretch(row,1); } void Export::showMe() { show(); updateCurveList(); } void Export::updateCurveList() { QString text("The following curves are active and to be exported:"); int cnt=0; SeaData *d; if (isHidden()) return; for (d = set->dataList.first(); d != 0; d = set->dataList.next()) { if (d->isActive()) { text.append("\n "); text.append(d->label); cnt++; } } if (cnt == 0) { text = "no active curves"; } text.append("\n\ncurves are de-/activated by clicking on their legend"); message->setText(text); show(); } void Export::progress(int bytes) { QString text; if (progressBytes < 0) return; if (isHidden()) return; progressBytes += bytes; if (progressBytes >= 0 && lastProgress.elapsed() > 250) { lastProgress.start(); text.sprintf("%.2f MBytes read", progressBytes * 0.000001); message->setText(text); show(); procEvt(); } } void Export::exportXY() { QString cmd; QString line; int iret, cnt, icol; bool ok; time_t dt, t, from, to, step, lastRead, basis; time_t i, lasti, len, siz, scale, mag, endi; int prec; SeaData *d; QString text; double val; double *data; double yy, yy0; FILE *fil; QString fileResult; double eps; static double undefpluseps = 0; fileResult = QFileDialog::getSaveFileName( filePath, QString::null, this, "save file dialog", "select file to save exported data" ); if (fileResult == "") { return; } filePath = fileResult; from = set->startRange; to = set->endRange; step = stepLE->text().toInt(); if (step == 0) { /* auto */ step = ((to - from) / 5000 + 1) * 5; } from = (from / step) * step; scale = scaleLE->text().toInt(); if (scale < 1) { scale = 1; } len = (to - from - 1) / step; to = from + len * step; if (step == 1) { cmd.sprintf("graph %ld %ld text", from, to); } else { cmd.sprintf("graph %ld %ld np %ld", from, to, to - from + 2); } cnt = 0; for (d = set->dataList.first(); d != 0; d = set->dataList.next()) { if (d->isActive()) { cmd.append(" "); cmd.append(d->name); cnt++; } } if (cnt == 0) { message->setText("no curves active"); show(); return; } siz = len * cnt; data = (double *)malloc(siz * sizeof(*data)); if (data == NULL) { message->setText("no memory"); show(); return; } progressBytes = 0; message->setText("waiting for server"); procEvt(); lastProgress.start(); iret = set->ec->command(cmd); progressBytes = -1; if (iret < 0) { message->setText("can not connect to the GraphServer"); goto err2; } //printf("%s\n", cmd.latin1()); text = "Curves:"; message->setText(text); procEvt(); iret = set->ec->getLine(line); if (iret <= 0) { message->setText("can not get response 1"); goto err2; } //printf("> %s\n", line.latin1()); /* get returned absolute time */ lastRead = line.toLong(); //sscanf(line, "%ld", &lastRead); iret = set->ec->getLine(line); if (iret <= 0) { message->setText("can not get response 2"); goto err2; } //printf("> %s\n", line.latin1()); if (!line.startsWith("*")) { message->setText("missing *"); goto err2; } icol = 0; fil = fopen(filePath.latin1(), "w"); fprintf(fil, "# SEA export from %s\n", instrument); fprintf(fil, "# col 1: Time/%d sec since %s 0:00\n", (int)scale, set->dateLabel(0).latin1()); endi = 0; for (d = set->dataList.first(); d != 0; set->dataList.findRef(d), d = set->dataList.next()) { if (d->isActive()) { yy0 = DATA_UNDEF; yy = DATA_UNDEF; lasti = -1; //printf("- %s\n", d->label.latin1()); fprintf(fil, "# col %d: %s (%s) %s\n", icol + 2, d->name.latin1(), d->label.latin1(), d->row->tagLabel->text().latin1()); text.append("\n "); text.append(d->label); line = line.section(' ', 0, 0); if (d->name == line.mid(1)) { t = 0; do { iret = set->ec->getLine(line); if (iret <= 0) { message->setText("can not get line"); goto err; } //printf("> %s\n", line.latin1()); if (line.startsWith("*")) { i = len; } else { /* decode line to x[n] / y[n] */ dt = line.section(' ', 0, 0).toLong(&ok); /* iret = sscanf(line, "%ld %n", &dt, &pos); if (iret < 1) { */ if (!ok) { message->setText("bad timestep"); goto err; } t += dt; i = (t - from) / step; yy0 = yy; yy = line.section(' ', 1, 1).toDouble(&ok); //iret = sscanf(line + pos, "%lf", &yy); // printf("scan %8ld %9.4f\n", t - from, yy); if (!ok) { // not a valid value yy = DATA_UNDEF; } else { if (yy == DATA_UNDEF) { // by chance if (undefpluseps == 0) { // create closest possible (but different) value to DATA_UNDEF undefpluseps = yy; eps = undefpluseps * 1e-9; while (undefpluseps == DATA_UNDEF) { undefpluseps += eps; eps = eps * 2; } } yy = undefpluseps; } } } /*---*/ if (lasti < i) { if (lasti < 0) { lasti = 0; } while (lasti < i - 1 && lasti < len) { assert(lasti * cnt + icol < siz); data[lasti*cnt + icol] = yy0; lasti++; } if (lasti < len) { data[lasti*cnt + icol] = yy; // printf("%ld %9.4f\n", lasti, yy); if (yy != DATA_UNDEF) { if (lasti > endi && lasti != len) endi = lasti; } } lasti++; } } while (!line.startsWith("*")); } else { for (i = 0; isetText(text); procEvt(); } } //fprintf(fil, "\n"); basis = (from - set->base) / step; //printf("endi %ld\n", endi); for (i = 0; i < endi; i++) { if (scale == 1) { fprintf(fil, "%ld", (basis + i) * step); } else { mag = 10 * scale / step; for (prec = 0; mag > 1; prec++,mag/=10); fprintf(fil, "%.*f", prec, (double)(basis + i) * step / scale); } for (icol = 0; icol < cnt; icol++) { val = data[i*cnt + icol]; if (val == DATA_UNDEF) { fprintf(fil, "\t%s", noneLE->text().latin1()); } else { // fprintf(fil, "\t%.7g", val); // we might write here full precision, this will not watse space in case step is not 1 fprintf(fil, "\t%.14g", val); } } fprintf(fil,"\n"); } text.append("\n\nwritten to\n"); text.append(filePath.latin1()); message->setText(text); err: fclose(fil); err2: free(data); show(); }