From f0e6d0b8ae7c5752f21c53e57d544b6491dde563 Mon Sep 17 00:00:00 2001 From: Dan Jordan Date: Wed, 9 Sep 2020 15:20:20 -0500 Subject: [PATCH 1/3] Add GitHub actions for Ubuntu-latest and CentOS 7 Builds and runs the app with -h. Also clarify/add content to README --- .github/workflows/nominal-testing.yml | 40 +++++++++++++++++++++ README | 50 ++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/nominal-testing.yml diff --git a/.github/workflows/nominal-testing.yml b/.github/workflows/nominal-testing.yml new file mode 100644 index 0000000..74882cc --- /dev/null +++ b/.github/workflows/nominal-testing.yml @@ -0,0 +1,40 @@ +name: Koviz Testing Actions + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test-ubuntu: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: install prerequisites + run: sudo apt-get update && sudo apt-get install qtbase5-dev qt5-default + - name: qmake + run: qmake + - name: make + run: make -j3 + - name: koviz -h + run: ./bin/koviz -h + + test-centos7: + + runs-on: ubuntu-latest + container: + image: centos:7 + + steps: + - uses: actions/checkout@v2 + - name: install prerequisites + run: yum update && yum install -y qt5-qtbase-devel gcc gcc-c++ make flex bison + - name: qmake + run: qmake-qt5 + - name: make + run: make -j3 + - name: koviz -h + run: ./bin/koviz -h diff --git a/README b/README index 8067727..2bff7f4 100644 --- a/README +++ b/README @@ -1,9 +1,41 @@ -% git clone https://github.com/nasa/koviz.git -% cd koviz -% qmake-qt5 - If command not found, install Qt: - redhat> sudo yum install qt5-qtbase-devel - ubuntu> sudo apt-get install qtbase5-dev -% make -% bin/koviz -h ; # for usage -% bin/koviz RUN_dir|MONTE_dir ; # View trick run or monte carlo data +# Get the Code +```sh +git clone https://github.com/nasa/koviz.git +``` +# Qt Prerequisites + +`koviz` is built upon the Qt framework. + +## Redhat 7+ + +```sh +sudo yum install qt5-qtbase-devel gcc gcc-c++ make flex bison +``` + +## Ubuntu latest +```sh +sudo apt-get install qtbase5-dev qt5-default +``` + +# Build + +## Redhat + +```sh +qmake-qt5 +make +``` +## Ubuntu + +```sh +qmake +make +``` + +# Run + +```sh +bin/koviz -h # for usage +bin/koviz /path/to/RUN_dir # View trick run +bin/koviz /path/to/MONTE_dir # View trick MONTE dir (set of runs) +``` From 302895e9f6ee6b5eb65d9072060386f23bef10a7 Mon Sep 17 00:00:00 2001 From: Dan Jordan Date: Wed, 9 Sep 2020 16:42:52 -0500 Subject: [PATCH 2/3] Rename README to README.md since GitHub is so picky :\ --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From 8d073dc651e3d30e3ab3a40f7b2aed9fda3fb9ed Mon Sep 17 00:00:00 2001 From: Dan Jordan Date: Tue, 8 Sep 2020 15:40:35 -0500 Subject: [PATCH 3/3] Support generic tab-delimited CSV-style monte_runs Provides the ability to read the monte_runs file in a non-trick-specific format that external monte-carlo tools can leverage --- koviz/main.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 5 deletions(-) diff --git a/koviz/main.cpp b/koviz/main.cpp index 549e35e..7f811e1 100644 --- a/koviz/main.cpp +++ b/koviz/main.cpp @@ -54,6 +54,8 @@ QStandardItemModel* monteInputModelTrick07(const QString &monteInputFile, const QStringList &runs); QStandardItemModel* monteInputModelTrick17(const QString &monteInputFile, const QStringList &runs); +QStandardItemModel* monteInputModelCSV(const QString &monteInputFile, + const QStringList &runs); QStringList runsSubset(const QStringList& runsList, const QString &filterPattern, const QString& excludePattern, uint beginRun, uint endRun); @@ -1835,20 +1837,26 @@ QStandardItemModel* monteInputModel(const QString &monteDir, } QTextStream in(&file); - bool isTrick07 = false; + unsigned int trickVersion = 0; while (!in.atEnd()) { QString line = in.readLine(); if ( line.startsWith("NUM_RUNS:") ) { - isTrick07 = true; + trickVersion = 7; + break; + } else if ( line.startsWith("#NAME:") ) { + trickVersion = 17; break; } + // Other else if's go here if Trick changes format AGAIN. } file.close(); - if ( isTrick07 ) { + if ( trickVersion >= 7 && trickVersion < 17 ) { m = monteInputModelTrick07(monteInputFile,runs); - } else { + } else if (trickVersion >= 17) { m = monteInputModelTrick17(monteInputFile,runs); + } else { + m = monteInputModelCSV(monteInputFile,runs); } return m; @@ -2071,7 +2079,7 @@ QStandardItemModel* monteInputModelTrick17(const QString &monteInputFile, // // Get number of runs - // + // TODO: Is this even doing anything? nRuns immediately overwritten after this bool isCount = false; int nRuns = 0; in.seek(0); // Go to beginning of file @@ -2175,6 +2183,114 @@ QStandardItemModel* monteInputModelTrick17(const QString &monteInputFile, return m; } +QStandardItemModel* monteInputModelCSV(const QString &monteInputFile, + const QStringList& runs) +{ + QStandardItemModel* m = 0; + + QFile file(monteInputFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + fprintf(stderr,"koviz [error]: could not open %s\n", + monteInputFile.toLatin1().constData()); + exit(-1); + } + QTextStream in(&file); + + // + // Sanity check - top line should be #NAME: + // + QString line = in.readLine(); + if ( !line.startsWith("RunId") ) { + fprintf(stderr,"koviz [error]: error parsing %s. " + "First line should begin with \"RunId\"\n", + monteInputFile.toLatin1().constData()); + exit(-1); + } + + // + // Get Vars + // + QStringList vars = line.split(QRegExp("\\s+"),QString::SkipEmptyParts); + + // + // Allocate table items + // + int nRuns = runs.size(); // If beginRun,endRun set, runs could be a subset + m = new QStandardItemModel(nRuns,vars.size()); + + // + // Set table header for rows and get begin/end run ids + // TODO: this code is duplicated in multiple places + int beginRun = INT_MAX; + int endRun = 0; + int r = 0 ; + foreach ( QString run, runs ) { + int runId = run.mid(4).toInt(); // 4 is for RUN_ + if ( runId < beginRun ) { + beginRun = runId; + } + if ( runId > endRun ) { + endRun = runId; + } + QString runName = QString("%0").arg(runId); + m->setHeaderData(r,Qt::Vertical,runName); + r++; + } + // + // Data + // + int lineNum = 1; + in.seek(0); // Go to beginning of file + line = in.readLine(); // Skip first header line + // TODO: much of this but not all is repeated code from Trick17 version + while (!in.atEnd()) { + ++lineNum; + line = in.readLine(); + QStringList vals = line.split(QRegExp("\\s+"),QString::SkipEmptyParts); + if ( vals.size() != vars.size() ) { + fprintf(stderr, "koviz [error]: error parsing %s. There " + "are %d variables specified in top line, " + "but only %d values on line number %d.\n", + monteInputFile.toLatin1().constData(), + vars.size(),vals.size(),lineNum); + exit(-1); + } + + int runId = vals.at(0).toInt(); + if ( runId < beginRun || runId > endRun ) { + continue; + } + + QString runName= QString("%0").arg(runId); + runName = runName.rightJustified(5, '0'); + runName.prepend("RUN_"); + if ( ! runs.contains(runName) ) { + // Run is in the monte carlo input file, + // but it is not in the runs list. + // Assume that RUN was excluded intentionally, + // and not missing. + continue; + } + + int nv = vals.size(); + for ( int c = 0; c < nv; ++c) { + QString val = vals.at(c) ; + double v = val.toDouble(); + if ( c == 0 ) { + int ival = val.toInt(); + val = val.sprintf("%d",ival); + } else { + val = val.sprintf("%.4lf",v); + } + NumSortItem *item = new NumSortItem(val); + m->setItem(lineNum+1,c,item); + m->setHeaderData(c,Qt::Horizontal,vars.at(c)); + } + } + file.close(); + + return m; +} QStandardItemModel* runsInputModel(const QStringList &runs) {