From c1209fb0f1f01309bd7e054e5a0054d04b319d42 Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Thu, 11 Jul 2024 17:14:38 -0600 Subject: [PATCH 01/35] add cfg --- src/gui/mainWindow.cpp | 23 +++++++++++++++++++-- src/ninja/cli.cpp | 47 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 93e816d8..9595ac45 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -28,6 +28,8 @@ *****************************************************************************/ #include "mainWindow.h" +#include +#include mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent) @@ -85,6 +87,7 @@ mainWindow::mainWindow(QWidget *parent) meshCellSize = 200.0; checkMessages(); + QString v(NINJA_VERSION_STRING); v = "Welcome to WindNinja " + v; @@ -124,6 +127,7 @@ void mainWindow::checkMessages(void) { mbox.exec(); abort(); } + else { char *papszMsg = NinjaQueryServerMessages(false); @@ -1657,15 +1661,28 @@ void mainWindow::openOutputPath() int mainWindow::solve() { + + std::ofstream outFile("config.cfg"); + + // Check if the file was opened successfully + if (!outFile) { + std::cerr << "Error: Could not open the file for writing!" << std::endl; + return 1; + } + + #ifdef NINJAFOAM bool useNinjaFoam = tree->ninjafoam->ninjafoamGroupBox->isChecked(); #endif //disable the open output path button tree->solve->openOutputPathButton->setDisabled( true ); - + //dem file std::string demFile = inputFileName.toStdString(); - + outFile << demFile; + + outFile.close(); + #ifdef NINJAFOAM std::string caseFile = existingCaseDir.toStdString(); #endif @@ -1759,6 +1776,8 @@ int mainWindow::solve() else if( tree->weather->weatherGroupBox->isChecked() ) initMethod = WindNinjaInputs::wxModelInitializationFlag; + + //input wind height double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits inHeightUnits; diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index a73b3ded..71e694aa 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -30,6 +30,9 @@ #include "cli.h" #include +#include +#include +#include /** * Function used to check that 'opt1' and 'opt2' are not specified @@ -137,6 +140,8 @@ const std::string* get_checked_elevation_file (po::variables_map& vm) } } + + /** * Command line implementation (CLI) of WindNinja. Can be run using command line args or * from an input file. @@ -166,6 +171,8 @@ int windNinjaCLI(int argc, char* argv[]) // Moved to initializeOptions() try { + + cout << "WindNinja_cli ../../data/cli_wxModelInitialization_diurnal.cfg" << endl; // Declare a group of options that will be // allowed only on command line po::options_description generic("Generic options"); @@ -373,9 +380,10 @@ int windNinjaCLI(int argc, char* argv[]) po::parsed_options opts_command = po::command_line_parser(argc, argv). options(cmdline_options).extra_parser(at_option_parser).positional(p).run(); - //write out parsed options for debugging + if(writeParsed) { + typedef std::vector< po::basic_option > vec_opt; cout << "\n\nParsed command line options:" << endl; for(vec_opt::iterator l_itrOpt = opts_command.options.begin(); @@ -394,8 +402,41 @@ int windNinjaCLI(int argc, char* argv[]) cout << endl; } } + + cout << "WindNinja_cli ../../data/cli_wxModelInitialization_diurnal.cfg" << endl; + store(opts_command, vm); //notify(vm); + cout << "WindNinja_cli ../../data/cli_wxModelInitialization_diurnal.cfg" << endl; + + ofstream outFile("config2.cfg"); + + if (!outFile) { + cerr << "Error: Could not open the file for writing!" << endl; + return; + } + + for (const auto& pair : vm) { + const string& option_name = pair.first; + const boost::program_options::variable_value& option_value = pair.second; + + outFile << "Option '" << option_name << "': "; + if (option_value.value().type() == typeid(bool)) { + outFile << (option_value.as() ? "true" : "false") << endl; + } else if (option_value.value().type() == typeid(string)) { + outFile << option_value.as() << endl; + } else { + outFile << "Unknown type" << endl; + } + } + + // This flush is actually optional because close() will flush automatically + outFile.flush(); + outFile.close(); + + cout << "File writing complete." << endl; + + if( argc == 1 ) { @@ -1276,10 +1317,10 @@ int windNinjaCLI(int argc, char* argv[]) option_dependency(vm, "wx_station_filename", "start_day"); option_dependency(vm, "wx_station_filename", "start_hour"); option_dependency(vm, "wx_station_filename", "start_minute"); - option_dependency(vm, "wx_station_filename", "stop_year"); option_dependency(vm, "wx_station_filename", "stop_month"); option_dependency(vm, "wx_station_filename", "stop_day"); - option_dependency(vm, "wx_station_filename", "stop_hour"); + option_dependency(vm, "wx_station_ffilename", "stop_year"); + option_dependency(vm, "wx_station_ilename", "stop_hour"); option_dependency(vm, "wx_station_filename", "stop_minute"); option_dependency(vm, "wx_station_filename", "number_time_steps"); timeList = pointInitialization::getTimeList( vm["start_year"].as(), From d54881b77c358b25db52076ea260766df6fdb25a Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Fri, 12 Jul 2024 16:41:50 -0600 Subject: [PATCH 02/35] extract zip working --- src/gui/mainWindow.cpp | 85 +++++++++++++++++++++++++++++++++++++++++- src/gui/mainWindow.h | 4 +- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 9595ac45..c4806be4 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -28,8 +28,15 @@ *****************************************************************************/ #include "mainWindow.h" +#include +#include #include #include +#include "gdal_util.h" +#include "cpl_vsi.h" +#include "cpl_error.h" +#include "cpl_string.h" +#include "gdal.h" mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent) @@ -198,6 +205,8 @@ void mainWindow::writeSettings() writeToConsole("Settings saved."); } + + void mainWindow::readSettings() { QSettings settings(QSettings::UserScope, "Firelab", "WindNinja"); @@ -1658,6 +1667,64 @@ void mainWindow::openOutputPath() QUrl::TolerantMode ) ); } } +void mainWindow::addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName) { + + VSILFILE *fin; + fin = VSIFOpenL(fileToAdd.c_str(), "r"); + if (fin == NULL) { + std::cerr << "Failed to open file: " << fileToAdd << std::endl; + return; + } + + vsi_l_offset offset; + VSIFSeekL(fin, 0, SEEK_END); + offset = VSIFTellL(fin); + VSIRewindL(fin); + + char *data = (char*)CPLMalloc(offset * sizeof(char)); + if (data == NULL) { + std::cerr << "Failed to allocate memory for file data." << std::endl; + VSIFCloseL(fin); + return; + } + if (VSIFReadL(data, 1, offset, fin) != offset) { + std::cerr << "Failed to read file contents: " << fileToAdd << std::endl; + CPLFree(data); + VSIFCloseL(fin); + return; + } + VSIFCloseL(fin); + + void* zipHandle = CPLCreateZip(zipFilePath.c_str(), NULL); + if (zipHandle == NULL) { + std::cerr << "Failed to create or open zip file: " << zipFilePath << std::endl; + CPLFree(data); + return; + } + + if (CPLCreateFileInZip(zipHandle, zipEntryName.c_str(), NULL) != CE_None) { + std::cerr << "Failed to create file in zip: " << zipEntryName << std::endl; + CPLFree(data); + CPLCloseZip(zipHandle); + return; + } + + if (CPLWriteFileInZip(zipHandle, data, static_cast(offset)) != CE_None) { + std::cerr << "Failed to write data to file in zip: " << zipEntryName << std::endl; + } + + if (CPLCloseFileInZip(zipHandle) != CE_None) { + std::cerr << "Failed to close file in zip: " << zipEntryName << std::endl; + } + + CPLCloseZip(zipHandle); + + CPLFree(data); + + std::cout << "File added to ZIP: " << zipEntryName << std::endl; +} + + int mainWindow::solve() { @@ -1679,9 +1746,8 @@ int mainWindow::solve() //dem file std::string demFile = inputFileName.toStdString(); - outFile << demFile; + outFile << "--elevation_file " + demFile; - outFile.close(); #ifdef NINJAFOAM std::string caseFile = existingCaseDir.toStdString(); @@ -1698,6 +1764,7 @@ int mainWindow::solve() vegetation = WindNinjaInputs::brush; else if( vegIndex == 2 ) vegetation = WindNinjaInputs::trees; + outFile << "--vegetation " + vegetation; } //mesh @@ -1720,6 +1787,18 @@ int mainWindow::solve() else meshUnits = lengthUnits::meters; } + outFile << "--meshchoice " + meshChoice; + outFile << "--mesh_resolution " + std::to_string(meshRes); + + outFile << "--units_mesh_resolution " + meshUnits; + + std::string zipFilePath = "example.zip"; + + outFile.close(); + + addFileToZip(zipFilePath, "config.cfg", "config.cfg"); + + #ifdef NINJAFOAM WindNinjaInputs::eNinjafoamMeshChoice ninjafoamMeshChoice; if(useNinjaFoam){ @@ -2905,6 +2984,8 @@ int mainWindow::checkSpdDirItem() } return status; } + + int mainWindow::checkPointItem() { eInputStatus status = blue; diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index 16434d5f..4ade01d3 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -183,9 +183,9 @@ class mainWindow : public QMainWindow void treeDoubleClick(QTreeWidgetItem *item, int column); bool getLatLon(); - + void test(); - + void addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName); int solve(); void cancelSolve(); int countRuns(); From 08e5bf7ecd7497db265ccd9086d3775f003eb604 Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Mon, 15 Jul 2024 16:53:15 -0600 Subject: [PATCH 03/35] newclass --- src/gui/mainWindow.cpp | 64 ++++--------------------------------- src/ninja/CMakeLists.txt | 1 + src/ninja/casefile.cpp | 69 ++++++++++++++++++++++++++++++++++++++++ src/ninja/casefile.h | 39 +++++++++++++++++++++++ src/ninja/ninja.cpp | 18 ++++++++++- 5 files changed, 133 insertions(+), 58 deletions(-) create mode 100644 src/ninja/casefile.cpp create mode 100644 src/ninja/casefile.h diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index c4806be4..a26b9219 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -32,11 +32,9 @@ #include #include #include -#include "gdal_util.h" #include "cpl_vsi.h" #include "cpl_error.h" #include "cpl_string.h" -#include "gdal.h" mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent) @@ -1667,62 +1665,8 @@ void mainWindow::openOutputPath() QUrl::TolerantMode ) ); } } -void mainWindow::addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName) { - - VSILFILE *fin; - fin = VSIFOpenL(fileToAdd.c_str(), "r"); - if (fin == NULL) { - std::cerr << "Failed to open file: " << fileToAdd << std::endl; - return; - } - - vsi_l_offset offset; - VSIFSeekL(fin, 0, SEEK_END); - offset = VSIFTellL(fin); - VSIRewindL(fin); - - char *data = (char*)CPLMalloc(offset * sizeof(char)); - if (data == NULL) { - std::cerr << "Failed to allocate memory for file data." << std::endl; - VSIFCloseL(fin); - return; - } - if (VSIFReadL(data, 1, offset, fin) != offset) { - std::cerr << "Failed to read file contents: " << fileToAdd << std::endl; - CPLFree(data); - VSIFCloseL(fin); - return; - } - VSIFCloseL(fin); - - void* zipHandle = CPLCreateZip(zipFilePath.c_str(), NULL); - if (zipHandle == NULL) { - std::cerr << "Failed to create or open zip file: " << zipFilePath << std::endl; - CPLFree(data); - return; - } - - if (CPLCreateFileInZip(zipHandle, zipEntryName.c_str(), NULL) != CE_None) { - std::cerr << "Failed to create file in zip: " << zipEntryName << std::endl; - CPLFree(data); - CPLCloseZip(zipHandle); - return; - } - if (CPLWriteFileInZip(zipHandle, data, static_cast(offset)) != CE_None) { - std::cerr << "Failed to write data to file in zip: " << zipEntryName << std::endl; - } - if (CPLCloseFileInZip(zipHandle) != CE_None) { - std::cerr << "Failed to close file in zip: " << zipEntryName << std::endl; - } - - CPLCloseZip(zipHandle); - - CPLFree(data); - - std::cout << "File added to ZIP: " << zipEntryName << std::endl; -} @@ -1840,12 +1784,18 @@ int mainWindow::solve() QVariant temp = tree->surface->timeZone->tzComboBox->itemData( tzIndex ); std::string timeZone = temp.toString().toStdString(); + + outFile << "--time_zone " + timeZone; + //diurnal bool useDiurnal = tree->diurnal->diurnalGroupBox->isChecked(); + outFile << "--diurnal_winds " + useDiurnal; + //stability bool useStability = tree->stability->stabilityGroupBox->isChecked(); - + + outFile << "--non_neutral_stability " + useStability; //initialization method WindNinjaInputs::eInitializationMethod initMethod; if( tree->wind->windGroupBox->isChecked() ) diff --git a/src/ninja/CMakeLists.txt b/src/ninja/CMakeLists.txt index bcf88ebd..0a71022c 100644 --- a/src/ninja/CMakeLists.txt +++ b/src/ninja/CMakeLists.txt @@ -31,6 +31,7 @@ set(NINJA_SOURCES air.cpp ascii_grid.cpp Array2D.cpp Aspect.cpp + casefile.cpp cellDiurnal.cpp cli.cpp dbfopen.cpp diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp new file mode 100644 index 00000000..4ed8f7d1 --- /dev/null +++ b/src/ninja/casefile.cpp @@ -0,0 +1,69 @@ +#include "casefile.h" + +class CaseFile { +public: + void addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName) { + VSILFILE *fin; + fin = VSIFOpenL(fileToAdd.c_str(), "r"); + if (fin == NULL) { + std::cerr << "Failed to open file: " << fileToAdd << std::endl; + return; + } + + vsi_l_offset offset; + VSIFSeekL(fin, 0, SEEK_END); + offset = VSIFTellL(fin); + VSIRewindL(fin); + + char *data = (char*)CPLMalloc(offset * sizeof(char)); + if (data == NULL) { + std::cerr << "Failed to allocate memory for file data." << std::endl; + VSIFCloseL(fin); + return; + } + if (VSIFReadL(data, 1, offset, fin) != offset) { + std::cerr << "Failed to read file contents: " << fileToAdd << std::endl; + CPLFree(data); + VSIFCloseL(fin); + return; + } + VSIFCloseL(fin); + + void* zipHandle = CPLCreateZip(zipFilePath.c_str(), NULL); + if (zipHandle == NULL) { + std::cerr << "Failed to create or open zip file: " << zipFilePath << std::endl; + CPLFree(data); + return; + } + + if (CPLCreateFileInZip(zipHandle, zipEntryName.c_str(), NULL) != CE_None) { + std::cerr << "Failed to create file in zip: " << zipEntryName << std::endl; + CPLFree(data); + CPLCloseZip(zipHandle); + return; + } + + if (CPLWriteFileInZip(zipHandle, data, static_cast(offset)) != CE_None) { + std::cerr << "Failed to write data to file in zip: " << zipEntryName << std::endl; + } + + if (CPLCloseFileInZip(zipHandle) != CE_None) { + std::cerr << "Failed to close file in zip: " << zipEntryName << std::endl; + } + + CPLCloseZip(zipHandle); + + CPLFree(data); + + std::cout << "File added to ZIP: " << zipEntryName << std::endl; + } + + void deleteFileFromPath(std::string directoryPath, std::string Filename) { + for (const auto& entry : std::filesystem::directory_iterator(directoryPath)) { + if (entry.is_regular_file() && entry.path().filename() == Filename) { + std::filesystem::remove(entry.path()); // Use std::filesystem explicitly + std::cout << "Deleted file: " << entry.path() << std::endl; + } + } + } +}; diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h new file mode 100644 index 00000000..59aba635 --- /dev/null +++ b/src/ninja/casefile.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * $Id$ + * + * Project: WindNinja + * Purpose: Input/Output Handling of Casefile for VTK + * Author: Rui Zhang + * + ****************************************************************************** + * + * THIS SOFTWARE WAS DEVELOPED AT THE ROCKY MOUNTAIN RESEARCH STATION (RMRS) + * MISSOULA FIRE SCIENCES LABORATORY BY EMPLOYEES OF THE FEDERAL GOVERNMENT + * IN THE COURSE OF THEIR OFFICIAL DUTIES. PURSUANT TO TITLE 17 SECTION 105 + * OF THE UNITED STATES CODE, THIS SOFTWARE IS NOT SUBJECT TO COPYRIGHT + * PROTECTION AND IS IN THE PUBLIC DOMAIN. RMRS MISSOULA FIRE SCIENCES + * LABORATORY ASSUMES NO RESPONSIBILITY WHATSOEVER FOR ITS USE BY OTHER + * PARTIES, AND MAKES NO GUARANTEES, EXPRESSED OR IMPLIED, ABOUT ITS QUALITY, + * RELIABILITY, OR ANY OTHER CHARACTERISTIC. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +#include +#include +#include "cpl_vsi.h" +#include "gdal.h" + +class CaseFile { +public: + void addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName); + void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); +}; \ No newline at end of file diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 2ea31bf3..29b3e92a 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2798,8 +2798,10 @@ void ninja::setUvGrids (AsciiGrid& angGrid, AsciiGrid& velGrid, * Writes VTK, FARSITE ASCII Raster, text comparison, shape, and kmz output files. */ + void ninja::writeOutputFiles() { + set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); //Write volume data to VTK format (always in m/s?) @@ -2813,8 +2815,22 @@ void ninja::writeOutputFiles() } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "binary";//"binary";//"ascii"; + volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - }catch (exception& e) + std::string directoryPath = ""; + std::string nameFile = ""; + size_t found = input.volVTKFile.find_last_of("/"); + if (found != std::string::npos) { + directoryPath = input.volVTKFile.substr(0, found); // Extract substring up to the last '/' + nameFile = input.volVTKFile.substr(found + 1); // Extract substring after the last '/' + } + + addFileToZip(directoryPath + "/example.zip", input.volVTKFile, nameFile); + + deleteVTKFromPath(directoryPath input.volVTKFile); + + } + catch (exception& e) { input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); }catch (...) From 70a1a384fe9dfa7493ab93c263b44ad8b1c66d2f Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Mon, 22 Jul 2024 16:31:17 -0600 Subject: [PATCH 04/35] initial casefile -noinputs --- src/gui/mainWindow.cpp | 40 ++++--- src/gui/mainWindow.h | 1 - src/ninja/casefile.cpp | 248 +++++++++++++++++++++++++++++++++-------- src/ninja/casefile.h | 37 +++++- src/ninja/ninja.cpp | 56 ++++++++-- src/ninja/ninja.h | 5 +- 6 files changed, 308 insertions(+), 79 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index caac0eee..a0d6ccc4 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -30,8 +30,8 @@ #include "mainWindow.h" #include #include -#include #include +#include #include "cpl_vsi.h" #include "cpl_error.h" #include "cpl_string.h" @@ -1669,10 +1669,13 @@ void mainWindow::openOutputPath() int mainWindow::solve() { + CaseFile casefile; + std::string getdir = tree->solve->outputDirectory().toStdString(); + std::string inputpath = getdir + "/config.cfg"; + + std::ofstream outFile(inputpath); - std::ofstream outFile("config.cfg"); - // Check if the file was opened successfully if (!outFile) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; @@ -1688,6 +1691,8 @@ int mainWindow::solve() //dem file std::string demFile = inputFileName.toStdString(); outFile << "--elevation_file " + demFile; + + #ifdef NINJAFOAM @@ -1707,7 +1712,6 @@ int mainWindow::solve() vegetation = WindNinjaInputs::trees; outFile << "--vegetation " + vegetation; } - //mesh int meshIndex = tree->surface->meshResComboBox->currentIndex(); Mesh::eMeshChoice meshChoice; @@ -1728,17 +1732,21 @@ int mainWindow::solve() else meshUnits = lengthUnits::meters; } - outFile << "--meshchoice " + meshChoice; - outFile << "--mesh_resolution " + std::to_string(meshRes); - - outFile << "--units_mesh_resolution " + meshUnits; - - std::string zipFilePath = "example.zip"; - outFile.close(); + ///outFile << "--meshchoice " + meshChoice;f + // outFile << "--mesh_resolution " + std::to_string(meshRes); - addFileToZip(zipFilePath, "config.cfg", "config.cfg"); - + //outFile << "--units_mesh_resolution " + meshUnits; + + std::string getfileName = casefile.parse("file", inputFileName.toStdString()); + std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; + casefile.setdir(getdir); + casefile.setzip(zipFilePath); + outFile.close(); + + casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); #ifdef NINJAFOAM WindNinjaInputs::eNinjafoamMeshChoice ninjafoamMeshChoice; @@ -1782,17 +1790,17 @@ int mainWindow::solve() std::string timeZone = temp.toString().toStdString(); - outFile << "--time_zone " + timeZone; + //outFile << "--time_zone " + timeZone; //diurnal bool useDiurnal = tree->diurnal->diurnalGroupBox->isChecked(); - outFile << "--diurnal_winds " + useDiurnal; + // outFile << "--diurnal_winds " + useDiurnal; //stability bool useStability = tree->stability->stabilityGroupBox->isChecked(); - outFile << "--non_neutral_stability " + useStability; + // outFile << "--non_neutral_stability " + useStability; //initialization method WindNinjaInputs::eInitializationMethod initMethod; if( tree->wind->windGroupBox->isChecked() ) diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index 4ade01d3..f6f2deb4 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -185,7 +185,6 @@ class mainWindow : public QMainWindow bool getLatLon(); void test(); - void addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName); int solve(); void cancelSolve(); int countRuns(); diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 4ed8f7d1..8454fc5f 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -1,69 +1,219 @@ #include "casefile.h" -class CaseFile { -public: - void addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName) { - VSILFILE *fin; - fin = VSIFOpenL(fileToAdd.c_str(), "r"); - if (fin == NULL) { - std::cerr << "Failed to open file: " << fileToAdd << std::endl; - return; - } +std::string CaseFile::zipfilename = ""; +std::string CaseFile::directory = ""; - vsi_l_offset offset; - VSIFSeekL(fin, 0, SEEK_END); - offset = VSIFTellL(fin); - VSIRewindL(fin); +std::mutex zipMutex; - char *data = (char*)CPLMalloc(offset * sizeof(char)); - if (data == NULL) { - std::cerr << "Failed to allocate memory for file data." << std::endl; - VSIFCloseL(fin); - return; - } - if (VSIFReadL(data, 1, offset, fin) != offset) { - std::cerr << "Failed to read file contents: " << fileToAdd << std::endl; - CPLFree(data); - VSIFCloseL(fin); - return; +CaseFile::CaseFile() { +} + +bool CaseFile::isCfgFile(const std::string& filePath) { + const std::string extension = ".cfg"; + if (filePath.length() >= extension.length()) { + std::string fileExtension = filePath.substr(filePath.length() - extension.length()); + return fileExtension == extension; + } else { + return false; + } +} + +bool CaseFile::isVTKFile(const std::string& filePath) { + const std::string extension = ".vtk"; + if (filePath.length() >= extension.length()) { + std::string fileExtension = filePath.substr(filePath.length() - extension.length()); + return fileExtension == extension; + } else { + return false; + } +} + +bool CaseFile::lookforzip(const std::string& zipFilePath, const std::string& directory) { + char** papszDir = VSIReadDir(directory.c_str()); + if (papszDir != nullptr) { + + for (int i = 0; papszDir[i] != nullptr; i++) { + std::string entry = papszDir[i]; + + if (entry == "." || entry == "..") { + continue; } - VSIFCloseL(fin); - void* zipHandle = CPLCreateZip(zipFilePath.c_str(), NULL); - if (zipHandle == NULL) { - std::cerr << "Failed to create or open zip file: " << zipFilePath << std::endl; - CPLFree(data); - return; + if (entry == parse("file", getzip())) { + return true; } + } + + CSLDestroy(papszDir); + } + return false; +} - if (CPLCreateFileInZip(zipHandle, zipEntryName.c_str(), NULL) != CE_None) { - std::cerr << "Failed to create file in zip: " << zipEntryName << std::endl; - CPLFree(data); - CPLCloseZip(zipHandle); +bool CaseFile::lookfordate(const std::string& date) { + return false; +} + + +std::string CaseFile::parse(const std::string& type, const std::string& path) { + size_t found = path.find_last_of("/"); + if (found != std::string::npos) { + if (strcmp(type.c_str(), "directory") == 0) { + return path.substr(0, found); + + } + else + if (strcmp(type.c_str(), "file") == 0) { + return path.substr(found + 1); // Extract substring after the last '/' + } + } +} + + +void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath) { + // Enable CPL logging + std::lock_guard lock(zipMutex); // for multithreading issue?? not sure I think i busted it + CPLSetConfigOption("CPL_DEBUG", "ON"); + + std::cout << "ZIP File Path: " << zipFilePath << std::endl; + std::cout << "Directory Path: " << dirPath << std::endl; + std::cout << "File to Add Path: " << usrlocalpath << std::endl; + std::cout << "File to Add: " << fileToAdd << std::endl; + + bool foundzip = lookforzip(zipFilePath, dirPath); + std::cout << "Found ZIP: " << foundzip << std::endl; + + if (foundzip) { + std::ifstream infile(zipFilePath); + if (!infile.good()) { + std::cerr << "ZIP file does not exist: " << zipFilePath << std::endl; return; } + } - if (CPLWriteFileInZip(zipHandle, data, static_cast(offset)) != CE_None) { - std::cerr << "Failed to write data to file in zip: " << zipEntryName << std::endl; - } + zipFile zip; + if (!foundzip) { + zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_CREATE); + std::cout << "Creating new ZIP file: " << zipFilePath << std::endl; + } else { + zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_ADDINZIP); + std::cout << "Appending to existing ZIP file: " << zipFilePath << std::endl; + } - if (CPLCloseFileInZip(zipHandle) != CE_None) { - std::cerr << "Failed to close file in zip: " << zipEntryName << std::endl; - } + if (zip == NULL) { + std::cerr << "Failed to open ZIP file: " << zipFilePath << std::endl; + CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open ZIP file %s", zipFilePath.c_str()); + const char* errMsg = CPLGetLastErrorMsg(); + std::cerr << "GDAL Error: " << errMsg << std::endl; + return; + } - CPLCloseZip(zipHandle); + zip_fileinfo zi = {0}; + if (cpl_zipOpenNewFileInZip(zip, fileToAdd.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { + std::cerr << "Could not open new file in ZIP: " << fileToAdd << std::endl; + CPLError(CE_Failure, CPLE_FileIO, "Could not open new file in ZIP %s", fileToAdd.c_str()); + cpl_zipClose(zip, nullptr); + return; + } + + VSILFILE *file = VSIFOpenL(usrlocalpath.c_str(), "rb"); + if (file == nullptr) { + std::cerr << "Could not open file for reading with VSIL: " << usrlocalpath << std::endl; + CPLError(CE_Failure, CPLE_FileIO, "Could not open file for reading with VSIL %s", usrlocalpath.c_str()); + cpl_zipCloseFileInZip(zip); + cpl_zipClose(zip, nullptr); + return; + } + + VSIFSeekL(file, 0, SEEK_END); + vsi_l_offset fileSize = VSIFTellL(file); + VSIFSeekL(file, 0, SEEK_SET); + char *data = (char*)CPLMalloc(fileSize); + if (data == nullptr) { + std::cerr << "Failed to allocate memory for file data." << std::endl; + CPLError(CE_Failure, CPLE_OutOfMemory, "Failed to allocate memory for file data."); + VSIFCloseL(file); + cpl_zipCloseFileInZip(zip); + cpl_zipClose(zip, nullptr); + return; + } + + if (VSIFReadL(data, 1, fileSize, file) != fileSize) { + std::cerr << "Failed to read file contents: " << fileToAdd << std::endl; + CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents %s", fileToAdd.c_str()); CPLFree(data); + VSIFCloseL(file); + cpl_zipCloseFileInZip(zip); + cpl_zipClose(zip, nullptr); + return; + } - std::cout << "File added to ZIP: " << zipEntryName << std::endl; + if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) { + std::cerr << "Error writing data to ZIP file: " << fileToAdd << std::endl; + CPLError(CE_Failure, CPLE_FileIO, "Error writing data to ZIP file %s", fileToAdd.c_str()); } - void deleteFileFromPath(std::string directoryPath, std::string Filename) { - for (const auto& entry : std::filesystem::directory_iterator(directoryPath)) { - if (entry.is_regular_file() && entry.path().filename() == Filename) { - std::filesystem::remove(entry.path()); // Use std::filesystem explicitly - std::cout << "Deleted file: " << entry.path() << std::endl; - } + CPLFree(data); + VSIFCloseL(file); + cpl_zipCloseFileInZip(zip); + + if (cpl_zipClose(zip, nullptr) != ZIP_OK) { + std::cerr << "Error closing ZIP file" << std::endl; + CPLError(CE_Failure, CPLE_FileIO, "Error closing ZIP file %s", zipFilePath.c_str()); + } + std::cout << "File added to ZIP: " << fileToAdd << std::endl; +} + + + +std::string CaseFile::getTime() { + auto now = std::chrono::system_clock::now(); + + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + + std::tm* local_tm = std::localtime(&now_time_t); + + std::ostringstream oss; + oss << std::put_time(local_tm, "%Y-%m-%d %H:%M:%S"); + return oss.str(); +} + + +void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filename) { + + char** papszDir = VSIReadDir(directoryPath.c_str()); + if (papszDir != nullptr) { + + for (int i = 0; papszDir[i] != nullptr; i++) { + std::string entry = papszDir[i]; + + if (entry == "." || entry == "..") { + continue; + } + + std::string fullPath = directoryPath + "/" + entry; + + if (entry == filename) { + VSIUnlink(fullPath.c_str()); } + + } + + CSLDestroy(papszDir); + } +} + void CaseFile::setdir(std::string dir) { + directory = dir; + } + + std::string CaseFile::getzip() { + return zipfilename; + } + + void CaseFile::setzip(std::string zip) { + zipfilename = zip; + } + + std::string CaseFile::getdir() { + return directory; } -}; diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 59aba635..17a5e05c 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -28,12 +28,47 @@ *****************************************************************************/ #include +#include #include #include "cpl_vsi.h" #include "gdal.h" +#include +#include +#include +#include +#include "cpl_minizip_zip.h" +#include +#include +#include +#include +#include "cpl_error.h" class CaseFile { + +private: + static std::string zipfilename; + + static std::string directory; + public: - void addFileToZip(const std::string& zipFilePath, const std::string& fileToAdd, const std::string& zipEntryName); + CaseFile(); + +void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath); void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); + bool lookforzip(const std::string& zipFilePath, const std::string& directory); + bool isCfgFile(const std::string& filePath); + bool isVTKFile(const std::string& filePath); + +std::string parse(const std::string& type, const std::string& path) ; +std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); +bool lookfordate(const std::string& date) ; + +std::string getTime(); +std::string getdir() ; + void setdir(std::string dir); + + std::string getzip () ; + void setzip(std::string zip); + + }; \ No newline at end of file diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 29b3e92a..33e18817 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2799,9 +2799,22 @@ void ninja::setUvGrids (AsciiGrid& angGrid, AsciiGrid& velGrid, */ + + +std::string ninja::converttimetostd(const boost::local_time::local_date_time& ninjaTime) { + std::ostringstream ss; + + ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); + + ss << ninjaTime; + + std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); + return result; +} + + void ninja::writeOutputFiles() { - set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); //Write volume data to VTK format (always in m/s?) @@ -2817,18 +2830,39 @@ void ninja::writeOutputFiles() std::string vtkWriteFormat = "binary";//"binary";//"ascii"; volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string directoryPath = ""; - std::string nameFile = ""; - size_t found = input.volVTKFile.find_last_of("/"); - if (found != std::string::npos) { - directoryPath = input.volVTKFile.substr(0, found); // Extract substring up to the last '/' - nameFile = input.volVTKFile.substr(found + 1); // Extract substring after the last '/' + CaseFile casefile; + std::string directoryPath = get_outputPath(); + std::string normfile = casefile.parse("file", input.volVTKFile); + std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); + std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); + + std::string timestr = ""; + std:: string getlocaltime = casefile.getTime(); + + //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; + if (input.ninjaTime.is_not_a_date_time()) { + timestr = getlocaltime; } - - addFileToZip(directoryPath + "/example.zip", input.volVTKFile, nameFile); + else { + timestr = converttimetostd(input.ninjaTime); + + } + std::cout << timestr << std::endl; - deleteVTKFromPath(directoryPath input.volVTKFile); + std::string getfileName = casefile.parse("file", input.dem.fileName); + std::string zipFilePath = casefile.getzip(); + std::cout << zipFilePath << std::endl; + std::cout << directoryPath << std::endl; + + std::cout << input.volVTKFile << std::endl; + std::cout << normfile << std::endl; + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + casefile.deleteFileFromPath(directoryPath , normfile); + casefile.deleteFileFromPath(directoryPath , surfFile); } catch (exception& e) { @@ -4794,12 +4828,12 @@ void ninja::set_outputPath(std::string path) ** stub, we are using GenerateTempFile to be cross platform. We are just ** using the stub/basename instead of the whole path. */ + const char *pszTmpName = CPLGetBasename(CPLGenerateTempFilename(0)); const char *pszTestPath = CPLFormFilename(path.c_str(), pszTmpName, 0); int nRet; if( VSI_ISDIR( sStat.st_mode ) ){ - //see if we can write to this path nRet = VSIMkdir(pszTestPath, 0777); if(nRet == 0){ VSIRmdir(pszTestPath); diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index 0a07db93..ad6c164d 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -59,7 +59,7 @@ #include "cpl_string.h" #include "ninja_conv.h" - +#include "casefile.h" #include "constants.h" #include "ascii_grid.h" #include "SurfProperties.h" @@ -480,6 +480,9 @@ class ninja void computeUVWField(); void prepareOutput(); bool matched(int iter); + + + std::string converttimetostd(const boost::local_time::local_date_time& ninjaTime) ; void writeOutputFiles(); void deleteDynamicMemory(); From 5d6ae243f4c6eafbb12b1aab6e51c77daf370d6f Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Thu, 1 Aug 2024 13:17:07 -0600 Subject: [PATCH 05/35] inputs sort of working finally --- src/gui/mainWindow.cpp | 557 ++++++++++++++++++++++++++++++++++------- src/gui/mainWindow.h | 1 + 2 files changed, 470 insertions(+), 88 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index a0d6ccc4..48922cd3 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -28,13 +28,6 @@ *****************************************************************************/ #include "mainWindow.h" -#include -#include -#include -#include -#include "cpl_vsi.h" -#include "cpl_error.h" -#include "cpl_string.h" mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent) @@ -1586,6 +1579,7 @@ int mainWindow::checkInputFile(QString fileName) tree->surface->timeZone->tzCheckBox->setChecked(true); int nIndex = tree->surface->timeZone->tzComboBox->findText(oTimeZone); tree->surface->timeZone->tzComboBox->setCurrentIndex(nIndex); + } //emit latLonChanged( ll[0], ll[1], false ); @@ -1665,38 +1659,42 @@ void mainWindow::openOutputPath() - - int mainWindow::solve() { - CaseFile casefile; + CaseFile casefile; std::string getdir = tree->solve->outputDirectory().toStdString(); std::string inputpath = getdir + "/config.cfg"; - + std::ofstream outFile(inputpath); - if (!outFile) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; } + #ifdef NINJAFOAM bool useNinjaFoam = tree->ninjafoam->ninjafoamGroupBox->isChecked(); + if (useNinjaFoam) { + outFile << "--momentum_flag true"; + } #endif //disable the open output path button tree->solve->openOutputPathButton->setDisabled( true ); //dem file std::string demFile = inputFileName.toStdString(); - outFile << "--elevation_file " + demFile; - - - - + + outFile << "--elevation_file " << demFile; + #ifdef NINJAFOAM + std::string caseFile = existingCaseDir.toStdString(); + if (useNinjaFoam) { + outFile << "--existing_case_directory" << caseFile; + } + #endif //vegetation/roughness @@ -1704,13 +1702,18 @@ int mainWindow::solve() WindNinjaInputs::eVegetation vegetation; if( inputFileType != LCP ) { //get choice from combo - if(vegIndex == 0) + if(vegIndex == 0) { vegetation = WindNinjaInputs::grass; - else if( vegIndex == 1 ) + outFile << "--vegetation grass\n"; + } + else if( vegIndex == 1 ) { vegetation = WindNinjaInputs::brush; - else if( vegIndex == 2 ) + outFile << "--vegetation brush\n"; + } + else if( vegIndex == 2 ) { vegetation = WindNinjaInputs::trees; - outFile << "--vegetation " + vegetation; + outFile << "--vegetation trees\n"; + } } //mesh int meshIndex = tree->surface->meshResComboBox->currentIndex(); @@ -1718,35 +1721,37 @@ int mainWindow::solve() double meshRes; lengthUnits::eLengthUnits meshUnits; bool customMesh = false; - if( meshIndex == 0 ) + if( meshIndex == 0 ) { meshChoice = Mesh::coarse; - else if( meshIndex == 1 ) + outFile << "--mesh_choice coarse\n"; + } + else if( meshIndex == 1 ) { meshChoice = Mesh::medium; - else if( meshIndex == 2 ) + + outFile << "--mesh_choice medium\n"; + } + else if( meshIndex == 2 ) { meshChoice = Mesh::fine; + + outFile << "--mesh_choice fine\n"; + } else { meshRes = tree->surface->meshResDoubleSpinBox->value(); customMesh = true; - if( tree->surface->meshFeetRadioButton->isChecked() ) + } + if( tree->surface->meshFeetRadioButton->isChecked() ) { meshUnits = lengthUnits::feet; - else + outFile << "--units_mesh_resolution ft\n"; + + } + else { meshUnits = lengthUnits::meters; + outFile << "--units_mesh_resolution m\n"; } - ///outFile << "--meshchoice " + meshChoice;f - // outFile << "--mesh_resolution " + std::to_string(meshRes); + outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; - //outFile << "--units_mesh_resolution " + meshUnits; - - std::string getfileName = casefile.parse("file", inputFileName.toStdString()); - std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; - casefile.setdir(getdir); - casefile.setzip(zipFilePath); - outFile.close(); - casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); #ifdef NINJAFOAM WindNinjaInputs::eNinjafoamMeshChoice ninjafoamMeshChoice; @@ -1770,6 +1775,7 @@ int mainWindow::solve() //location int tzIndex = tree->surface->timeZone->tzComboBox->currentIndex(); + if(tzIndex == -1 && (tree->diurnal->diurnalGroupBox->isChecked() || tree->weather->weatherGroupBox->isChecked() || tree->stability->stabilityGroupBox->isChecked() @@ -1787,110 +1793,210 @@ int mainWindow::solve() } QVariant temp = tree->surface->timeZone->tzComboBox->itemData( tzIndex ); - std::string timeZone = temp.toString().toStdString(); + std::string timeZone = temp.toString().toStdString(); - //outFile << "--time_zone " + timeZone; + outFile << "--time_zone " << timeZone <<"\n"; //diurnal bool useDiurnal = tree->diurnal->diurnalGroupBox->isChecked(); - - // outFile << "--diurnal_winds " + useDiurnal; + if (useDiurnal == 0) { + outFile << "--diurnal_winds false\n"; + } + else { + outFile << "--diurnal_winds true\n"; + } //stability bool useStability = tree->stability->stabilityGroupBox->isChecked(); - - // outFile << "--non_neutral_stability " + useStability; + if (useStability == 0) { + outFile << "--non_neutral_stability false\n"; + } + else { + + outFile << "--non_neutral_stability true\n"; + } + //initialization method WindNinjaInputs::eInitializationMethod initMethod; - if( tree->wind->windGroupBox->isChecked() ) + if( tree->wind->windGroupBox->isChecked() ) { initMethod = WindNinjaInputs::domainAverageInitializationFlag; - else if( tree->point->pointGroupBox->isChecked() ) - initMethod = WindNinjaInputs::pointInitializationFlag; - else if( tree->weather->weatherGroupBox->isChecked() ) - initMethod = WindNinjaInputs::wxModelInitializationFlag; + outFile << "--initialization_method domainAverageInitialization\n"; + } + else if( tree->point->pointGroupBox->isChecked() ) { + initMethod = WindNinjaInputs::pointInitializationFlag; + outFile << "--initialization_method pointInitialization\n"; + } + else if( tree->weather->weatherGroupBox->isChecked() ) { + initMethod = WindNinjaInputs::wxModelInitializationFlag; + outFile << "--initialization_method wxModelInitialization\n" ; + } + + + //input wind height double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits inHeightUnits; - if(tree->wind->metaWind->feetRadioButton->isChecked()) + + outFile << "--input_wind_height " << std::to_string(inHeight) << "\n" ; + if(tree->wind->metaWind->feetRadioButton->isChecked()) { inHeightUnits = lengthUnits::feet; - else + + outFile << "--units_input_wind_height ft\n"; + }else { inHeightUnits = lengthUnits::meters; + outFile << "--units_input_wind_height m\n"; + } + + // handle widget download DEM in widgetdownloadDEM.cpp + //speed units and air temp units velocityUnits::eVelocityUnits inputSpeedUnits; - if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) + + if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) { inputSpeedUnits = velocityUnits::milesPerHour; - else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) + + outFile << "--input_speed_units mph\n" ; + } + else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) { inputSpeedUnits = velocityUnits::metersPerSecond; - else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) + + outFile << "--input_speed_units mps\n"; + } + else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) { inputSpeedUnits = velocityUnits::knots; - else + + outFile << "--input_speed_units kts\n"; + } + else { inputSpeedUnits = velocityUnits::kilometersPerHour; - temperatureUnits::eTempUnits tempUnits; - if(tree->wind->windTable->airTempUnits->currentIndex() == 0) + outFile << "--input_speed_units kph\n" ; + } + temperatureUnits::eTempUnits tempUnits; + if(tree->wind->windTable->airTempUnits->currentIndex() == 0) + { tempUnits = temperatureUnits::F; + + outFile << "--air_temp_units F\n" ; + } else if(tree->wind->windTable->airTempUnits->currentIndex() == 1) + { tempUnits = temperatureUnits::C; + outFile << "--air_temp_units C\n"; + } //model init std::string weatherFile; QModelIndex mi = tree->weather->treeView->selectionModel()->currentIndex(); + if( mi.isValid() ) { QFileInfo fi( tree->weather->model->fileInfo( mi ) ); weatherFile = fi.absoluteFilePath().toStdString(); + + outFile << "--wx_model_type"; + outFile << "--forecast_duration"<< tree->weather->hourSpinBox->value() <<"\n"; + } + else weatherFile = ""; //output height double outHeight = tree->output->outputHeight->outputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits outHeightUnits; - if(tree->output->outputHeight->feetRadioButton->isChecked()) - outHeightUnits = lengthUnits::feet; - else + + outFile << "--output_wind_height " <output->outputHeight->feetRadioButton->isChecked()) { + + outFile << "--units_output_wind_height ft\n"; + + + outHeightUnits = lengthUnits::feet; + } + else { outHeightUnits = lengthUnits::meters; + outFile << "--units_output_wind_height m\n"; + } + velocityUnits::eVelocityUnits outputSpeedUnits; - if(tree->output->outputSpeedUnitsCombo->currentIndex() == 0) + if(tree->output->outputSpeedUnitsCombo->currentIndex() == 0) { outputSpeedUnits = velocityUnits::milesPerHour; - else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) + + outFile << "--output_speed_units mph\n"; + } + else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) { outputSpeedUnits = velocityUnits::metersPerSecond; - else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) + + outFile << "--output_speed_units mps\n" ; + } + else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) { outputSpeedUnits = velocityUnits::kilometersPerHour; - else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) + + outFile << "--output_speed_units kph\n"; + } + else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) { outputSpeedUnits = velocityUnits::knots; + outFile << "--output_speed_units kts\n"; + } + //clip buffer? int clip = tree->output->bufferSpinBox->value(); - + if (clip) { + outFile << "output_buffer_clipping true\n"; + } bool writeWxOutput; if( tree->output->wxModelOutputCheckBox->isEnabled() ) writeWxOutput = tree->output->wxModelOutputCheckBox->isChecked(); - + //google bool writeGoogle = tree->google->googleGroupBox->isChecked(); + if (writeGoogle) { + outFile << "--write_goog_output true\n"; + if( initMethod == WindNinjaInputs::wxModelInitializationFlag) { + + outFile << "--write_wx_model_goog_output true\n"; + } + } + double googleRes = tree->google->googleResSpinBox->value(); + outFile << "--goog_out_resolution" << std::to_string(googleRes)<< "\n"; double vectorWidth = tree->google->vectorWidthDoubleSpinBox->value(); lengthUnits::eLengthUnits googleUnits; KmlVector::egoogSpeedScaling googleScale; //bool writeLegend = tree->google->legendGroupBox->isChecked(); - if(tree->google->googleMetersRadioButton->isChecked()) + if(tree->google->googleMetersRadioButton->isChecked()) { googleUnits = lengthUnits::meters; - else - googleUnits = lengthUnits::feet; - if(tree->google->uniformRangeRadioButton->isChecked()) + outFile << "--units_goog_out_resolution m\n"; + } + else { + googleUnits = lengthUnits::feet; + outFile << "--units_goog_out_resolution ft\n"; + } + if(tree->google->uniformRangeRadioButton->isChecked()) { googleScale = KmlVector::equal_interval; - else + } + else { googleScale = KmlVector::equal_color; - + } std::string googleScheme; bool googVectorScaling = tree->google->applyVectorScaling->isChecked(); + if (googVectorScaling) { + + outFile << "--goog_out_vector_scaling true\n"; + } + else { + + outFile << "--goog_out_vector_scaling false\n"; + } if(tree->google->colorblindBox->isChecked()) { std::string googCheckScheme; @@ -1900,50 +2006,90 @@ int mainWindow::solve() if (googCheckScheme=="Default") { googleScheme="default"; + outFile << "--goog_out_color_scheme ROYGB\n"; } if (googCheckScheme=="ROPGW (Red Orange Pink Green White)") { googleScheme="ROPGW"; + + outFile << "--goog_out_color_scheme ROPGW\n"; } if (googCheckScheme=="Oranges") { googleScheme="oranges"; + + outFile << "--goog_out_color_scheme oranges\n"; } if (googCheckScheme=="Blues") { googleScheme="blues"; + + outFile << "--goog_out_color_scheme blues\n"; } if (googCheckScheme=="Pinks") { googleScheme="pinks"; + + outFile << "--goog_out_color_scheme pinks\n"; } if (googCheckScheme=="Greens") { googleScheme="greens"; + + outFile << "--goog_out_color_scheme greens\n"; } if (googCheckScheme=="Magic Beans") { googleScheme="magic_beans"; + + outFile << "--goog_out_color_scheme magic_beans\n"; } if (googCheckScheme=="Pink to Green") { googleScheme="pink_to_green"; + + outFile << "--goog_out_color_scheme pink_to_green\n"; } } else { googleScheme="default"; + + outFile << "--goog_out_color_scheme ROYGB\n"; } + //ascii raster fb files bool writeFb = tree->fb->fbGroupBox->isChecked(); + double fbRes = tree->fb->fbResSpinBox->value(); + + outFile << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; + + if (writeFb) { + outFile << "--write_ascii_output true\n"; + } + + else { + outFile << "--write_wx_model_ascii_output false\n"; + + outFile << "--write_wx_model_ascii_output true\n"; + } + lengthUnits::eLengthUnits fbUnits; - if(tree->fb->fbMetersRadioButton->isChecked()) + if(tree->fb->fbMetersRadioButton->isChecked()) { fbUnits = lengthUnits::meters; - else + outFile << "--units_ascii_out_resolution m\n"; + } + else { fbUnits = lengthUnits::feet; + outFile << "--units_ascii_out_resolution ft\n"; + } //write atmosphere file? bool writeAtm = tree->fb->atmFileCheckBox->isChecked(); + if (writeAtm) { + outFile << "--write_farsite_atm true\n"; + } + if(writeAtm && writeFb) { if((outHeight == 20 && outHeightUnits == lengthUnits::feet && @@ -1970,23 +2116,71 @@ int mainWindow::solve() //shape bool writeShape = tree->shape->shapeGroupBox->isChecked(); + // do for wx + + if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) { + + if (writeShape) { + outFile << "--write_wx_model_shapefile_output true\n"; + } + else { + outFile << "--write_wx_model_shapefile_output alse\n"; + } + } + else { + if (writeShape) { + outFile << "--write_shapefile_output true\n"; + } + else { + outFile << "--write_shapefile_output false\n"; + } + } + double shapeRes = tree->shape->shapeResSpinBox->value(); + + outFile << "--shape_out_resolution " <shape->shapeMetersRadioButton->isChecked()) + if(tree->shape->shapeMetersRadioButton->isChecked()) { shapeUnits = lengthUnits::meters; - else + outFile << "--units_shape_out_resolution m\n"; + } + else{ shapeUnits = lengthUnits::feet; + outFile << "--units_shape_out_resolution ft\n"; + } //pdf bool writePdf = tree->pdf->pdfGroupBox->isChecked(); + if (writePdf) { + outFile << "--write_pdf_output true\n"; + } + else { + outFile << "--write_pdf_output false\n"; + } double pdfRes = tree->pdf->pdfResSpinBox->value(); + + outFile << "--pdf_out_resolution "<< std::to_string(pdfRes) <<"\n"; double pdfLineWidth = tree->pdf->vectorWidthDoubleSpinBox->value(); + + outFile << "--pdf_linewidth "<pdf->pdfMetersRadioButton->isChecked()) + if(tree->pdf->pdfMetersRadioButton->isChecked()) { + outFile << "--units_pdf_out_resolution m\n"; pdfUnits = lengthUnits::meters; - else + } + else { + + outFile << "--units_pdf_out_resolution ft\n"; pdfUnits = lengthUnits::feet; + } int pdfBase = tree->pdf->backgroundComboBox->currentIndex(); - + if (pdfBase == 0) { + + outFile << "--pdf_basemap topofire\n"; + } + else { + outFile << "--pdf_basemap hillshade\n"; + } + double pdfHeight, pdfWidth; int pdfSize = tree->pdf->sizeComboBox->currentIndex(); // Letter @@ -1994,18 +2188,23 @@ int mainWindow::solve() { pdfHeight = 11.0; pdfWidth = 8.5; + outFile << "--pdf_size letter\n" ; } // Legal else if( pdfSize == 1 ) { pdfHeight = 14.0; pdfWidth = 8.5; + + outFile << "--pdf_size legal\n"; } // Tabloid else if( pdfSize == 2 ) { pdfHeight = 17.0; pdfWidth = 11.0; + + outFile << "--pdf_size tabloid\n"; } if( tree->pdf->landscapeRadioButton->isChecked() ) { @@ -2016,10 +2215,18 @@ int mainWindow::solve() } bool writeVTK = tree->vtk->vtkGroupBox->isChecked(); + if (writeVTK) { + outFile << "--write_vtk_output true\n"; + } + else { + outFile << "--write_vtk_output false\n"; + } //number of processors int nThreads = tree->solve->numProcSpinBox->value(); + outFile << "--num_threads" + std::to_string(nThreads) + "\n" ; + #ifdef NINJAFOAM army = new ninjaArmy(1, useNinjaFoam); // ninjafoam solver #else @@ -2030,6 +2237,7 @@ int mainWindow::solve() { int pointFormat = tree->point->simType; std::vector pointFileList = tree->point->stationFileList; //This is for the new way + std::string pointFile = tree->point->stationFileList[0]; //For Old Format, only can accept 1 file std::vector xStartTime = tree->point->startSeries; //Get the start time from pointInput std::vector xEndTime = tree->point->endSeries; //Get the Stop time from pointInput @@ -2037,6 +2245,74 @@ int mainWindow::solve() bool useTimeList = tree->point->enableTimeseries; //Find out if its a timeseries run or not bool writeStationKML = tree->point->writeStationKmlButton->isChecked(); //Write a kml file bool writeStationCSV = tree->point->writeStationFileButton->isChecked(); //hidden for now + /* + if (tree->point->xWidget != NULL) { + + if (tree->point->xWidget->getBuffer() != "") { + + outFile << "--station_buffer " + tree->point->xWidget->getBuffer().toStdString(); + } + if (tree->point->xWidget->getBufferUnits() != "") { + + outFile << "--station_buffer_units " + tree->point->xWidget->getBufferUnits(); + } + if (tree->point->xWidget->getType() != "") { + + outFile << "--fetch_type " + tree->point->xWidget->getType(); + } + } +*/ + outFile << "--fetch_station_name "; + + if (useTimeList) { + + outFile << "--fetch_current_station_data false"; + + } + + else { + + outFile << "--fetch_current_station_data true"; + + } + + outFile << "wx_station_filename " << pointFile; + if (writeStationKML) { + + outFile << "--write_wx_station_kml true\n"; + } + else { + outFile << "--write_wx_station_kml false\n"; + + } + if (writeStationCSV) { + + outFile << "--write_wx_station_csv true\n"; + } + else { + outFile << "--write_wx_station_csv false\n"; + + } + + outFile << "--start_year" << xStartTime[0] << "\n"; + outFile << "--start_month" < timeList; if(useDiurnal==true || useStability==true) //means that the user is specifying time - { //Get that time and assign it to the simulation + { //Get that time and assign it to the simulation + //outFile << "--number_time_steps" + numTimeSteps.toStdString() ; std::vector xSingleTime = tree->point->diurnalTimeVec; boost::posix_time::ptime singleTime = pointInitialization::generateSingleTimeObject(xSingleTime[0],xSingleTime[1],xSingleTime[2],xSingleTime[3],xSingleTime[4],timeZone); timeList.push_back(singleTime); @@ -2082,7 +2361,9 @@ int mainWindow::solve() boost::posix_time::ptime noTime; timeList.push_back(noTime); } - try{ //Try to run windninja + try{ + //Try to run windninja + outFile << "--match_points true\n"; army->makeStationArmy(timeList,timeZone, pointFile, demFile, true,false); } catch(...){ //catch all exceptions and tell the user, prevent segfaults @@ -2114,6 +2395,7 @@ int mainWindow::solve() { formatVec.push_back(wxStation::GetHeaderVersion(pointFileList[i].c_str())); } + if (std::equal(formatVec.begin()+1,formatVec.end(),formatVec.begin())) //Make sure all the header versions are equal, in case one of them gets past all the gui checkss { CPLDebug("STATION_FETCH","HEADER VERSIONS ARE GOOD..."); @@ -2139,6 +2421,8 @@ int mainWindow::solve() CPLDebug("STATION_FETCH","FILES STORED..."); try{ //try running with timelist + + outFile << "--match_points true\n"; army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); //setting pointFileList[0] is just for header checks etc } catch(...){ //catch any and all exceptions and tell the user @@ -2169,9 +2453,12 @@ int mainWindow::solve() boost::posix_time::ptime singleTime = pointInitialization::generateSingleTimeObject(xSingleTime[0], xSingleTime[1],xSingleTime[2], xSingleTime[3],xSingleTime[4],timeZone); - timeList.push_back(singleTime); + + timeList.push_back(singleTime); pointInitialization::storeFileNames(pointFileList); try{ //try making the army with current data + + outFile << "--match_points true\n"; army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); } catch(...){ //catch any and all exceptions and tell the user @@ -2212,9 +2499,9 @@ int mainWindow::solve() delete army; return false; } - - + } + if (writeStationKML==true) //Write KMLS for each time step { writeToConsole("Writing Weather Station .kml"); @@ -2227,6 +2514,7 @@ int mainWindow::solve() } } // if (writeStationCSV==true) + const char *csvOpt = CPLGetConfigOption("WRITE_CSV","FALSE"); if(csvOpt!="FALSE") //The only way to write an interpolated CSV is to set a config option { @@ -2239,6 +2527,7 @@ int mainWindow::solve() } const char *metaOpt = CPLGetConfigOption("FETCH_METADATA","FALSE"); + if(metaOpt!="FALSE") //set a config option to get the metadata from the DEM { //There is also a button for this, that is hidden (see stationFetchWidget) writeToConsole("Fetching station metadata for DEM..."); @@ -2247,6 +2536,8 @@ int mainWindow::solve() std::string baseMeta = baseDem+"-metadata"; std::string metaPath = std::string(CPLFormFilename(pathDem.c_str(),baseMeta.c_str(),".csv")); CPLDebug("STATION_FETCH","Saving Metadata to: %s",metaPath.c_str()); + outFile << "--fetch_metadata true\n"; + outFile << "--metadata_filename" << metaPath<< "\n"; pointInitialization::fetchMetaData(metaPath,demFile,true); } } @@ -2278,9 +2569,31 @@ int mainWindow::solve() progressDialog->cancel(); return false; } - + std::vector times = tree->weather->timeList(); + + std::vector stringTimes; + + // Iterate over each element in the vector + for (const auto& time : times) + { + stringTimes.push_back(boost::posix_time::to_iso_string(time.local_time())); // Convert and add to vector + } + /* This can throw a badForecastFile */ + std::string outstr; + + for (size_t i = 0; i < stringTimes.size(); ++i) + { + outstr += stringTimes[i]; + if (i != stringTimes.size() - 1) { + outstr += "||"; + } + } + outFile << "--forecast_times" << outstr <<"\n"; + + outFile << "--forecast_filename" << weatherFile << "\n"; + try { #ifdef NINJAFOAM @@ -2325,6 +2638,8 @@ int mainWindow::solve() runProgress = new int[nRuns]; //I don't think this is needed anymore std::string outputDir = tree->solve->outputDirectory().toStdString(); + outFile << "--output_path " << outputDir<< "\n" ; + if( outputDir == "" ) { // This should never happen, so if it does, fix it. throw( "no output directory specified in solve page" ); @@ -2362,13 +2677,18 @@ int mainWindow::solve() else if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { //get speed + outFile << "--input_speed " <wind->windTable->speed[i]->value()) << "\n"; army->setInputSpeed( i, tree->wind->windTable->speed[i]->value(), inputSpeedUnits); //get direction + + outFile << "--input_direction " <wind->windTable->dir[i]->value()) <<"\n"; + army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); army->setInputWindHeight ( i, inHeight, inHeightUnits ); + } //set input output height @@ -2388,15 +2708,32 @@ int mainWindow::solve() { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { + + outFile << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; + + outFile << "--month " <wind->windTable->date[i]->date().month() << "\n"; + + outFile << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; + + outFile << "--hour " <wind->windTable->time[i]->time().hour() << "\n"; + + outFile << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; + army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), tree->wind->windTable->time[i]->time().hour(), tree->wind->windTable->time[i]->time().minute(), 0, timeZone ); + outFile << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; army->setUniAirTemp( i, tree->wind->windTable->airTemp[i]->value(), tempUnits ); + + outFile << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; + + outFile << "--cloud_cover_units percent" << "\n" ; + army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -2421,15 +2758,34 @@ int mainWindow::solve() { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { + outFile << "--year " <wind->windTable->date[i]->date().year() <<"\n"; + + outFile << "--month " <wind->windTable->date[i]->date().month() <<"\n"; + + outFile << "--day " <wind->windTable->date[i]->date().day() <<"\n"; + + outFile << "--hour " << + tree->wind->windTable->time[i]->time().hour()<< "\n"; + + outFile << "--minute "<< tree->wind->windTable->time[i]->time().minute()<<"\n"; + + army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), tree->wind->windTable->time[i]->time().hour(), tree->wind->windTable->time[i]->time().minute(), 0, timeZone ); + army->setUniAirTemp( i, tree->wind->windTable->airTemp[i]->value(), tempUnits ); + + outFile << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value() << "\n"; + + outFile << "--uni_air_temp " <wind->windTable->airTemp[i]->value() << "\n"; + outFile << "--cloud_cover_units percent"<< "\n"; + army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -2440,17 +2796,30 @@ int mainWindow::solve() army->setPosition( i, GDALCenterLat, GDALCenterLon ); } } + army->setStabilityFlag( i, useStability ); //set mesh stuff if( customMesh ) { + army->setMeshResolution( i, meshRes, meshUnits ); } else { #ifdef NINJAFOAM if(useNinjaFoam){ - army->setMeshCount( i, ninjafoamMeshChoice ); + if(ninjafoamMeshChoice == WindNinjaInputs::coarse){ + outFile << "--mesh_count 25000" << "\n"; + } + else if(meshChoice == WindNinjaInputs::medium){ + outFile << "--mesh_count 50000" << "\n"; + } + else if(meshChoice == WindNinjaInputs::fine){ + outFile << "--mesh_count 100000" << "\n"; + } + + army->setMeshCount( i, ninjafoamMeshChoice ); + outFile << "--number_of_iterations 300" <<"\n"; army->setNumberOfIterations( i, 300); } else @@ -2470,7 +2839,7 @@ int mainWindow::solve() //set number of cpus... //army.setnumberCPUs(1); - + army->setGoogOutFlag (i,writeGoogle); army->setGoogLineWidth (i,vectorWidth); army->setGoogResolution (i,googleRes,googleUnits); @@ -2500,6 +2869,18 @@ int mainWindow::solve() army->setNinjaComNumRuns( i, nRuns ); } + + //set Casefile Directory and Input + std::string getfileName = casefile.parse("file", inputFileName.toStdString()); + std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; + casefile.setdir(getdir); + casefile.setzip(zipFilePath); + outFile.close(); + + casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); + army->set_writeFarsiteAtmFile( writeAtm && writeFb ); for( unsigned int i = 0; i < army->getSize(); i++ ) diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index f6f2deb4..ea40d867 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -67,6 +67,7 @@ #include "setconfigdialog.h" + class mainWindow : public QMainWindow { Q_OBJECT From 0e92f001d56e5b77c1dd0f90adf520c96ee1310d Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Thu, 1 Aug 2024 15:16:01 -0600 Subject: [PATCH 06/35] cli scraping clean (finished) --- src/ninja/cli.cpp | 105 +++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 71e694aa..2a21e276 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -29,10 +29,6 @@ *****************************************************************************/ #include "cli.h" -#include -#include -#include -#include /** * Function used to check that 'opt1' and 'opt2' are not specified @@ -172,7 +168,7 @@ int windNinjaCLI(int argc, char* argv[]) // Moved to initializeOptions() try { - cout << "WindNinja_cli ../../data/cli_wxModelInitialization_diurnal.cfg" << endl; + // Declare a group of options that will be // allowed only on command line po::options_description generic("Generic options"); @@ -403,41 +399,9 @@ int windNinjaCLI(int argc, char* argv[]) } } - cout << "WindNinja_cli ../../data/cli_wxModelInitialization_diurnal.cfg" << endl; store(opts_command, vm); //notify(vm); - cout << "WindNinja_cli ../../data/cli_wxModelInitialization_diurnal.cfg" << endl; - - ofstream outFile("config2.cfg"); - - if (!outFile) { - cerr << "Error: Could not open the file for writing!" << endl; - return; - } - - for (const auto& pair : vm) { - const string& option_name = pair.first; - const boost::program_options::variable_value& option_value = pair.second; - - outFile << "Option '" << option_name << "': "; - if (option_value.value().type() == typeid(bool)) { - outFile << (option_value.as() ? "true" : "false") << endl; - } else if (option_value.value().type() == typeid(string)) { - outFile << option_value.as() << endl; - } else { - outFile << "Unknown type" << endl; - } - } - - // This flush is actually optional because close() will flush automatically - outFile.flush(); - outFile.close(); - - cout << "File writing complete." << endl; - - - if( argc == 1 ) { cout << visible << "\n"; @@ -482,6 +446,60 @@ int windNinjaCLI(int argc, char* argv[]) //notify(vm); } } + //helper for casefile output of CLI + CaseFile casefile; + std::string getdir = casefile.parse( "directory", vm["elevation_file"].as()); + + std::string inputpath = getdir + "/config.cfg"; + + std::ofstream outFile(inputpath); + if (!outFile) { + cerr << "Error: Could not open the file for writing!" << endl; + return; + } + + for (const auto& pair : vm) { + const std::string& option_name = pair.first; + const po::variable_value& option_value = pair.second; + + outFile << "--" << option_name << " "; + + try { + if (option_value.value().type() == typeid(int)) { + outFile << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(bool)) { + outFile << std::boolalpha << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(std::string)) { + outFile << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(double)) { + outFile << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(std::vector)) { + const auto& vec = option_value.as>(); + for (const auto& str : vec) { + outFile << str << " "; + } + outFile << std::endl; + } else { + outFile << "Unknown type" << std::endl; + } + } catch (const boost::bad_any_cast& e) { + outFile << "Bad cast: " << e.what() << std::endl; + } + } + + // This flush is actually optional because close() will flush automatically + + std::string getfileName = casefile.parse("file", vm["elevation_file"].as()); + std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; + casefile.setdir(getdir); + casefile.setzip(zipFilePath); + outFile.flush(); + outFile.close(); + + casefile.addFileToZip(zipFilePath, getdir, getfileName, vm["elevation_file"].as()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); + if (vm.count("help")) { cout << visible << "\n"; @@ -1101,8 +1119,9 @@ int windNinjaCLI(int argc, char* argv[]) { //Check to be sure that the user specifies right info conflicting_options(vm, "fetch_station", "wx_station_filename"); - + std::vector timeList; + if(vm["fetch_station"].as() == true) //download station and make appropriate size ninjaArmy { const char *api_key_conf_opt = CPLGetConfigOption("CUSTOM_API_KEY","FALSE"); @@ -1186,10 +1205,11 @@ int windNinjaCLI(int argc, char* argv[]) else if (vm["fetch_type"].as()=="stid") { option_dependency(vm,"fetch_type","fetch_station_name"); - + bool fetchSuccess = pointInitialization::fetchStationByName(vm["fetch_station_name"].as(), timeList, osTimeZone, vm["fetch_current_station_data"].as()); + if(fetchSuccess==false) //Fail to download data { pointInitialization::removeBadDirectory(stationPathName); //delete the generated dir @@ -1199,6 +1219,7 @@ int windNinjaCLI(int argc, char* argv[]) pointInitialization::writeStationLocationFile(stationPathName,*elevation_file,vm["fetch_current_station_data"].as()); } + else //If something else bad happens { pointInitialization::removeBadDirectory(stationPathName); //Get rid of generated dir @@ -1319,8 +1340,8 @@ int windNinjaCLI(int argc, char* argv[]) option_dependency(vm, "wx_station_filename", "start_minute"); option_dependency(vm, "wx_station_filename", "stop_month"); option_dependency(vm, "wx_station_filename", "stop_day"); - option_dependency(vm, "wx_station_ffilename", "stop_year"); - option_dependency(vm, "wx_station_ilename", "stop_hour"); + option_dependency(vm, "wx_station_filename", "stop_year"); + option_dependency(vm, "wx_station_filename", "stop_hour"); option_dependency(vm, "wx_station_filename", "stop_minute"); option_dependency(vm, "wx_station_filename", "number_time_steps"); timeList = pointInitialization::getTimeList( vm["start_year"].as(), @@ -1898,7 +1919,7 @@ int windNinjaCLI(int argc, char* argv[]) windsim.setPDFLineWidth( i_, vm["pdf_linewidth"].as() ); std::string pbm = vm["pdf_basemap"].as(); int pbs = 0; - if( pbm == "hillshade" ) + if( pbm == "" ) { pbs = 0; } From 0419196bf3c4b2763fd46ece0d584748859ff713 Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Thu, 1 Aug 2024 15:16:27 -0600 Subject: [PATCH 07/35] dependency --- src/ninja/cli.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ninja/cli.h b/src/ninja/cli.h index ba17522a..14d79c24 100644 --- a/src/ninja/cli.h +++ b/src/ninja/cli.h @@ -48,6 +48,7 @@ namespace po = boost::program_options; #include #include +#include //#include From e6e167c5fb10f7406d7105ec6b5e7ad4f749252c Mon Sep 17 00:00:00 2001 From: RuiZhang Date: Tue, 6 Aug 2024 15:26:36 -0600 Subject: [PATCH 08/35] casefile full --- src/gui/WidgetDownloadDEM.cpp | 11 + src/gui/mainWindow.cpp | 895 +++++++++++++++++++++------------ src/gui/mainWindow.h | 10 +- src/gui/pointInput.cpp | 40 +- src/gui/pointInput.h | 5 + src/gui/solvePage.cpp | 9 + src/gui/solvePage.h | 4 +- src/gui/stationFetchWidget.cpp | 58 ++- src/gui/stationFetchWidget.h | 15 +- src/ninja/casefile.cpp | 214 ++++---- src/ninja/casefile.h | 44 +- src/ninja/cli.cpp | 139 +++-- src/ninja/cli.h | 2 + src/ninja/ninja.cpp | 65 ++- src/ninja/ninja.h | 4 +- 15 files changed, 1012 insertions(+), 503 deletions(-) diff --git a/src/gui/WidgetDownloadDEM.cpp b/src/gui/WidgetDownloadDEM.cpp index 4da7acaa..f205cf20 100644 --- a/src/gui/WidgetDownloadDEM.cpp +++ b/src/gui/WidgetDownloadDEM.cpp @@ -28,6 +28,7 @@ *****************************************************************************/ #include "WidgetDownloadDEM.h" +#include "casefile.h" //#include WidgetDownloadDEM::WidgetDownloadDEM(QWidget *parent) @@ -221,6 +222,13 @@ void WidgetDownloadDEM::saveDEM() westBound = mbrl[0].toDouble(); demSelected = true; + std::vector boundsarr = {northBound, southBound, eastBound, westBound}; + + CaseFile casefile; + + casefile.setDownloadedFromDEM(true); + casefile.setBoundingBox(boundsarr); + QString fileName; double boundArray[] = {this->northBound, this->eastBound, this->southBound, this->westBound}; double *boundBox; @@ -357,6 +365,7 @@ void WidgetDownloadDEM::updateDEMSource(int index) { switch(index){ case 0: //SRTM + CaseFile::setElevSource("srtm"); fetcher = FetchFactory::GetSurfaceFetch(FetchFactory::SRTM, FindDataPath("/data")); northDEMBound = srtm_northBound; southDEMBound = srtm_southBound; @@ -366,6 +375,7 @@ void WidgetDownloadDEM::updateDEMSource(int index) break; #ifdef HAVE_GMTED case 1: //GMTED + CaseFile::setElevSource("gmted"); fetcher = FetchFactory::GetSurfaceFetch(FetchFactory::WORLD_GMTED, FindDataPath("/data")); northDEMBound = world_gmted_northBound; southDEMBound = world_gmted_southBound; @@ -376,6 +386,7 @@ void WidgetDownloadDEM::updateDEMSource(int index) #endif #ifdef WITH_LCP_CLIENT case 2: //LCP + CaseFile::setElevSource("lcp"); fetcher = FetchFactory::GetSurfaceFetch(FetchFactory::LCP, FindDataPath("/data")); northDEMBound = lcp_northBound; southDEMBound = lcp_southBound; diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 48922cd3..1c054846 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -125,7 +125,6 @@ void mainWindow::checkMessages(void) { } else { - char *papszMsg = NinjaQueryServerMessages(false); mbox.setText(papszMsg); @@ -193,8 +192,6 @@ void mainWindow::writeSettings() writeToConsole("Settings saved."); } - - void mainWindow::readSettings() { QSettings settings(QSettings::UserScope, "Firelab", "WindNinja"); @@ -1579,7 +1576,6 @@ int mainWindow::checkInputFile(QString fileName) tree->surface->timeZone->tzCheckBox->setChecked(true); int nIndex = tree->surface->timeZone->tzComboBox->findText(oTimeZone); tree->surface->timeZone->tzComboBox->setCurrentIndex(nIndex); - } //emit latLonChanged( ll[0], ll[1], false ); @@ -1659,40 +1655,96 @@ void mainWindow::openOutputPath() +std::vector mainWindow::split(const std::string &s, const std::string &delimiter) { + std::vector tokens; + size_t start = 0; + size_t end = s.find(delimiter); + while (end != std::string::npos) { + tokens.push_back(s.substr(start, end - start)); + start = end + delimiter.length(); + end = s.find(delimiter, start); + } + tokens.push_back(s.substr(start, end)); + return tokens; +} + + int mainWindow::solve() { - CaseFile casefile; - std::string getdir = tree->solve->outputDirectory().toStdString(); - std::string inputpath = getdir + "/config.cfg"; - - std::ofstream outFile(inputpath); + + CaseFile casefile; + std::string getdir = tree->solve->outputDirectory().toStdString(); + std::string inputpath = getdir + "/config.cfg"; + std::string stationCSVFILEPATH = getdir + "/selectedstations.csv"; + std::string getfileName = casefile.parse("file", inputFileName.toStdString()); + std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; + + casefile.setdir(getdir); + casefile.setzip(zipFilePath); + + std::ofstream outFile(inputpath); + + std::ofstream stationCSVFILE(stationCSVFILEPATH); + if (!outFile) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; } + if (!stationCSVFILE) { + std::cerr << "Error: Could not open the file for writing!" << std::endl; + return 1; + } + + if (!tree->solve->CaseFIBOX->isChecked()) { + + outFile.close(); + stationCSVFILE.close(); + + } + else { + casefile.setZipOpen(true); + } #ifdef NINJAFOAM bool useNinjaFoam = tree->ninjafoam->ninjafoamGroupBox->isChecked(); - if (useNinjaFoam) { - outFile << "--momentum_flag true"; + if (useNinjaFoam && tree->solve->CaseFIBOX->isChecked()) { + outFile << "--momentum_flag true\n"; } #endif //disable the open output path button tree->solve->openOutputPathButton->setDisabled( true ); - + //dem file std::string demFile = inputFileName.toStdString(); - outFile << "--elevation_file " << demFile; + if (tree->solve->CaseFIBOX->isChecked()) { + if (casefile.getDownloadedFromDEM() == true) { + std::vector vec = casefile.getBoundingBox(); + + outFile << "--fetch_elevation true" << "\n"; + outFile << "--north " << vec[0] << "\n"; + + outFile << "--south " << vec[1] << "\n"; + + outFile << "--west " << vec[2] << "\n"; + outFile << "--east " << vec[3] << "\n"; + + outFile << "--elevation_source " << casefile.getElevSource() << "\n"; + + } + else { + outFile << "--fetch_elevation false" << "\n"; + } + outFile << "--elevation_file " << demFile << "\n"; + } #ifdef NINJAFOAM - std::string caseFile = existingCaseDir.toStdString(); - if (useNinjaFoam) { - outFile << "--existing_case_directory" << caseFile; + if (useNinjaFoam && tree->solve->CaseFIBOX->isChecked()) { + outFile << "--existing_case_directory" << caseFile<< "\n"; } #endif @@ -1704,52 +1756,71 @@ int mainWindow::solve() //get choice from combo if(vegIndex == 0) { vegetation = WindNinjaInputs::grass; - outFile << "--vegetation grass\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--vegetation grass\n"; + } } else if( vegIndex == 1 ) { vegetation = WindNinjaInputs::brush; - outFile << "--vegetation brush\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--vegetation brush\n"; + } } else if( vegIndex == 2 ) { vegetation = WindNinjaInputs::trees; - outFile << "--vegetation trees\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--vegetation trees\n"; + } } } - //mesh + //mesh do resolution later int meshIndex = tree->surface->meshResComboBox->currentIndex(); Mesh::eMeshChoice meshChoice; double meshRes; lengthUnits::eLengthUnits meshUnits; bool customMesh = false; if( meshIndex == 0 ) { - meshChoice = Mesh::coarse; - outFile << "--mesh_choice coarse\n"; + meshChoice = Mesh::coarse; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--mesh_choice coarse\n"; + } } else if( meshIndex == 1 ) { - meshChoice = Mesh::medium; + meshChoice = Mesh::medium; - outFile << "--mesh_choice medium\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--mesh_choice medium\n"; + } } else if( meshIndex == 2 ) { - meshChoice = Mesh::fine; + meshChoice = Mesh::fine; - outFile << "--mesh_choice fine\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--mesh_choice fine\n"; + } } else { - meshRes = tree->surface->meshResDoubleSpinBox->value(); - customMesh = true; + meshRes = tree->surface->meshResDoubleSpinBox->value(); + customMesh = true; } + if( tree->surface->meshFeetRadioButton->isChecked() ) { meshUnits = lengthUnits::feet; - outFile << "--units_mesh_resolution ft\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_mesh_resolution ft\n"; + } } else { meshUnits = lengthUnits::meters; - outFile << "--units_mesh_resolution m\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_mesh_resolution m\n"; + } } - outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; + if (customMesh && tree->solve->CaseFIBOX->isChecked()) { + outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; + } @@ -1775,7 +1846,6 @@ int mainWindow::solve() //location int tzIndex = tree->surface->timeZone->tzComboBox->currentIndex(); - if(tzIndex == -1 && (tree->diurnal->diurnalGroupBox->isChecked() || tree->weather->weatherGroupBox->isChecked() || tree->stability->stabilityGroupBox->isChecked() @@ -1793,46 +1863,56 @@ int mainWindow::solve() } QVariant temp = tree->surface->timeZone->tzComboBox->itemData( tzIndex ); - std::string timeZone = temp.toString().toStdString(); - outFile << "--time_zone " << timeZone <<"\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--time_zone " << timeZone <<"\n"; + } //diurnal bool useDiurnal = tree->diurnal->diurnalGroupBox->isChecked(); - if (useDiurnal == 0) { - outFile << "--diurnal_winds false\n"; - } - else { - outFile << "--diurnal_winds true\n"; - } + //stability bool useStability = tree->stability->stabilityGroupBox->isChecked(); - if (useStability == 0) { - outFile << "--non_neutral_stability false\n"; - } - else { + + if (tree->solve->CaseFIBOX->isChecked()) { + if (useDiurnal == 0) { + outFile << "--diurnal_winds false\n"; + } + else { + outFile << "--diurnal_winds true\n"; + } + if (useStability == 0) { + outFile << "--non_neutral_stability false\n"; + } + else { - outFile << "--non_neutral_stability true\n"; + outFile << "--non_neutral_stability true\n"; + } } - //initialization method WindNinjaInputs::eInitializationMethod initMethod; if( tree->wind->windGroupBox->isChecked() ) { initMethod = WindNinjaInputs::domainAverageInitializationFlag; - - outFile << "--initialization_method domainAverageInitialization\n"; + + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--initialization_method domainAverageInitialization\n"; + } } else if( tree->point->pointGroupBox->isChecked() ) { initMethod = WindNinjaInputs::pointInitializationFlag; - outFile << "--initialization_method pointInitialization\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--initialization_method pointInitialization\n"; + } } else if( tree->weather->weatherGroupBox->isChecked() ) { initMethod = WindNinjaInputs::wxModelInitializationFlag; - outFile << "--initialization_method wxModelInitialization\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--initialization_method wxModelInitialization\n" ; + } } @@ -1841,68 +1921,85 @@ int mainWindow::solve() double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits inHeightUnits; - outFile << "--input_wind_height " << std::to_string(inHeight) << "\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_wind_height " << std::to_string(inHeight) << "\n" ; + } if(tree->wind->metaWind->feetRadioButton->isChecked()) { - inHeightUnits = lengthUnits::feet; + inHeightUnits = lengthUnits::feet; - outFile << "--units_input_wind_height ft\n"; - }else { - inHeightUnits = lengthUnits::meters; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_input_wind_height ft\n"; + } + } + else { + inHeightUnits = lengthUnits::meters; - outFile << "--units_input_wind_height m\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_input_wind_height m\n"; + } } // handle widget download DEM in widgetdownloadDEM.cpp //speed units and air temp units velocityUnits::eVelocityUnits inputSpeedUnits; - if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) { - inputSpeedUnits = velocityUnits::milesPerHour; + inputSpeedUnits = velocityUnits::milesPerHour; - outFile << "--input_speed_units mph\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_speed_units mph\n" ; + } } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) { - inputSpeedUnits = velocityUnits::metersPerSecond; + inputSpeedUnits = velocityUnits::metersPerSecond; - outFile << "--input_speed_units mps\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_speed_units mps\n"; + } } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) { - inputSpeedUnits = velocityUnits::knots; + inputSpeedUnits = velocityUnits::knots; - outFile << "--input_speed_units kts\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_speed_units kts\n"; + } } else { - inputSpeedUnits = velocityUnits::kilometersPerHour; + inputSpeedUnits = velocityUnits::kilometersPerHour; - outFile << "--input_speed_units kph\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_speed_units kph\n" ; + } } + temperatureUnits::eTempUnits tempUnits; if(tree->wind->windTable->airTempUnits->currentIndex() == 0) { - tempUnits = temperatureUnits::F; + tempUnits = temperatureUnits::F; - outFile << "--air_temp_units F\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--air_temp_units F\n" ; + } } - else if(tree->wind->windTable->airTempUnits->currentIndex() == 1) - { - tempUnits = temperatureUnits::C; + else if(tree->wind->windTable->airTempUnits->currentIndex() == 1){ + tempUnits = temperatureUnits::C; - outFile << "--air_temp_units C\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--air_temp_units C\n"; + } } //model init std::string weatherFile; QModelIndex mi = tree->weather->treeView->selectionModel()->currentIndex(); - if( mi.isValid() ) { QFileInfo fi( tree->weather->model->fileInfo( mi ) ); weatherFile = fi.absoluteFilePath().toStdString(); - outFile << "--wx_model_type"; - outFile << "--forecast_duration"<< tree->weather->hourSpinBox->value() <<"\n"; - + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--wx_model_type "; + outFile << "--forecast_duration "<< tree->weather->hourSpinBox->value() <<"\n"; + } } - else weatherFile = ""; @@ -1910,92 +2007,109 @@ int mainWindow::solve() double outHeight = tree->output->outputHeight->outputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits outHeightUnits; - outFile << "--output_wind_height " <solve->CaseFIBOX->isChecked()) { + outFile << "--output_wind_height " <output->outputHeight->feetRadioButton->isChecked()) { + if (tree->solve->CaseFIBOX->isChecked()) { outFile << "--units_output_wind_height ft\n"; - - outHeightUnits = lengthUnits::feet; + } + outHeightUnits = lengthUnits::feet; } else { - outHeightUnits = lengthUnits::meters; + outHeightUnits = lengthUnits::meters; - outFile << "--units_output_wind_height m\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_output_wind_height m\n";} } velocityUnits::eVelocityUnits outputSpeedUnits; if(tree->output->outputSpeedUnitsCombo->currentIndex() == 0) { outputSpeedUnits = velocityUnits::milesPerHour; - outFile << "--output_speed_units mph\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--output_speed_units mph\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) { outputSpeedUnits = velocityUnits::metersPerSecond; - outFile << "--output_speed_units mps\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--output_speed_units mps\n" ; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) { outputSpeedUnits = velocityUnits::kilometersPerHour; - outFile << "--output_speed_units kph\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--output_speed_units kph\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) { outputSpeedUnits = velocityUnits::knots; - outFile << "--output_speed_units kts\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--output_speed_units kts\n"; } } //clip buffer? int clip = tree->output->bufferSpinBox->value(); - if (clip) { - outFile << "output_buffer_clipping true\n"; - } + bool writeWxOutput; if( tree->output->wxModelOutputCheckBox->isEnabled() ) writeWxOutput = tree->output->wxModelOutputCheckBox->isChecked(); - + //google bool writeGoogle = tree->google->googleGroupBox->isChecked(); - if (writeGoogle) { - outFile << "--write_goog_output true\n"; - if( initMethod == WindNinjaInputs::wxModelInitializationFlag) { - outFile << "--write_wx_model_goog_output true\n"; - } + if (tree->solve->CaseFIBOX->isChecked()) { + if (writeGoogle) { + outFile << "--write_goog_output true\n"; + if( initMethod == WindNinjaInputs::wxModelInitializationFlag) { + + outFile << "--write_wx_model_goog_output true\n"; + } + } + if (clip) { + outFile << "output_buffer_clipping true\n"; } + } + double googleRes = tree->google->googleResSpinBox->value(); - outFile << "--goog_out_resolution" << std::to_string(googleRes)<< "\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_resolution " << std::to_string(googleRes)<< "\n"; } double vectorWidth = tree->google->vectorWidthDoubleSpinBox->value(); lengthUnits::eLengthUnits googleUnits; KmlVector::egoogSpeedScaling googleScale; //bool writeLegend = tree->google->legendGroupBox->isChecked(); if(tree->google->googleMetersRadioButton->isChecked()) { - googleUnits = lengthUnits::meters; + googleUnits = lengthUnits::meters; - outFile << "--units_goog_out_resolution m\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_goog_out_resolution m\n"; } } else { - googleUnits = lengthUnits::feet; - outFile << "--units_goog_out_resolution ft\n"; + googleUnits = lengthUnits::feet; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_goog_out_resolution ft\n"; } } - if(tree->google->uniformRangeRadioButton->isChecked()) { + if(tree->google->uniformRangeRadioButton->isChecked()) googleScale = KmlVector::equal_interval; - } - else { + else googleScale = KmlVector::equal_color; - } + std::string googleScheme; bool googVectorScaling = tree->google->applyVectorScaling->isChecked(); - if (googVectorScaling) { + + if (tree->solve->CaseFIBOX->isChecked()) { + if (googVectorScaling) { - outFile << "--goog_out_vector_scaling true\n"; - } - else { + outFile << "--goog_out_vector_scaling true\n"; + } + else { - outFile << "--goog_out_vector_scaling false\n"; + outFile << "--goog_out_vector_scaling false\n"; + } } if(tree->google->colorblindBox->isChecked()) { @@ -2006,90 +2120,100 @@ int mainWindow::solve() if (googCheckScheme=="Default") { googleScheme="default"; - outFile << "--goog_out_color_scheme ROYGB\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme ROYGB\n"; } } if (googCheckScheme=="ROPGW (Red Orange Pink Green White)") { googleScheme="ROPGW"; - outFile << "--goog_out_color_scheme ROPGW\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme ROPGW\n"; } } if (googCheckScheme=="Oranges") { googleScheme="oranges"; - outFile << "--goog_out_color_scheme oranges\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme oranges\n"; } } if (googCheckScheme=="Blues") { googleScheme="blues"; - outFile << "--goog_out_color_scheme blues\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme blues\n"; } } if (googCheckScheme=="Pinks") { googleScheme="pinks"; - outFile << "--goog_out_color_scheme pinks\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme pinks\n"; } } if (googCheckScheme=="Greens") { googleScheme="greens"; - outFile << "--goog_out_color_scheme greens\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme greens\n"; } } if (googCheckScheme=="Magic Beans") { googleScheme="magic_beans"; - outFile << "--goog_out_color_scheme magic_beans\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme magic_beans\n"; } } if (googCheckScheme=="Pink to Green") { googleScheme="pink_to_green"; - outFile << "--goog_out_color_scheme pink_to_green\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme pink_to_green\n"; } } } else { googleScheme="default"; - outFile << "--goog_out_color_scheme ROYGB\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--goog_out_color_scheme ROYGB\n"; } } - //ascii raster fb files bool writeFb = tree->fb->fbGroupBox->isChecked(); - double fbRes = tree->fb->fbResSpinBox->value(); - outFile << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; + if (tree->solve->CaseFIBOX->isChecked()) { - if (writeFb) { + if (writeFb) { outFile << "--write_ascii_output true\n"; - } + } - else { - outFile << "--write_wx_model_ascii_output false\n"; + if (writeFb && initMethod == WindNinjaInputs::wxModelInitializationFlag ) { outFile << "--write_wx_model_ascii_output true\n"; + + + } + outFile << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; + } lengthUnits::eLengthUnits fbUnits; if(tree->fb->fbMetersRadioButton->isChecked()) { - fbUnits = lengthUnits::meters; - outFile << "--units_ascii_out_resolution m\n"; + fbUnits = lengthUnits::meters; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_ascii_out_resolution m\n"; } } else { - fbUnits = lengthUnits::feet; - outFile << "--units_ascii_out_resolution ft\n"; + fbUnits = lengthUnits::feet; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_ascii_out_resolution ft\n"; } } //write atmosphere file? bool writeAtm = tree->fb->atmFileCheckBox->isChecked(); - if (writeAtm) { - outFile << "--write_farsite_atm true\n"; - } - + if(writeAtm && writeFb) { if((outHeight == 20 && outHeightUnits == lengthUnits::feet && @@ -2113,72 +2237,85 @@ int mainWindow::solve() return false; } } + //shape bool writeShape = tree->shape->shapeGroupBox->isChecked(); // do for wx - if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) { - if (writeShape) { - outFile << "--write_wx_model_shapefile_output true\n"; - } - else { - outFile << "--write_wx_model_shapefile_output alse\n"; - } + double shapeRes = tree->shape->shapeResSpinBox->value(); + + if (tree->solve->CaseFIBOX->isChecked()) { + if (writeAtm) { + outFile << "--write_farsite_atm true\n"; } - else { - if (writeShape) { - outFile << "--write_shapefile_output true\n"; + if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) { + + if (writeShape) { + outFile << "--write_wx_model_shapefile_output true\n"; + } + else { + outFile << "--write_wx_model_shapefile_output false\n"; + } } else { - outFile << "--write_shapefile_output false\n"; - } + if (writeShape) { + outFile << "--write_shapefile_output true\n"; + } + else { + outFile << "--write_shapefile_output false\n"; + } } - double shapeRes = tree->shape->shapeResSpinBox->value(); - outFile << "--shape_out_resolution " <shape->shapeMetersRadioButton->isChecked()) { + } + lengthUnits::eLengthUnits shapeUnits; + if(tree->shape->shapeMetersRadioButton->isChecked()) { shapeUnits = lengthUnits::meters; - outFile << "--units_shape_out_resolution m\n"; - } - else{ + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_shape_out_resolution m\n"; } + } + else{ shapeUnits = lengthUnits::feet; - outFile << "--units_shape_out_resolution ft\n"; - } + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_shape_out_resolution ft\n"; } + } //pdf bool writePdf = tree->pdf->pdfGroupBox->isChecked(); - if (writePdf) { - outFile << "--write_pdf_output true\n"; - } - else { - outFile << "--write_pdf_output false\n"; - } - double pdfRes = tree->pdf->pdfResSpinBox->value(); - outFile << "--pdf_out_resolution "<< std::to_string(pdfRes) <<"\n"; + double pdfRes = tree->pdf->pdfResSpinBox->value(); double pdfLineWidth = tree->pdf->vectorWidthDoubleSpinBox->value(); - outFile << "--pdf_linewidth "<pdf->pdfMetersRadioButton->isChecked()) { - outFile << "--units_pdf_out_resolution m\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_pdf_out_resolution m\n"; } pdfUnits = lengthUnits::meters; } else { - outFile << "--units_pdf_out_resolution ft\n"; - pdfUnits = lengthUnits::feet; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--units_pdf_out_resolution ft\n"; } + pdfUnits = lengthUnits::feet; } int pdfBase = tree->pdf->backgroundComboBox->currentIndex(); - if (pdfBase == 0) { - + + if (tree->solve->CaseFIBOX->isChecked()) { + if (writePdf) { + outFile << "--write_pdf_output true\n"; + } + else { + outFile << "--write_pdf_output false\n"; + } + outFile << "--pdf_out_resolution "<< std::to_string(pdfRes) <<"\n"; + outFile << "--pdf_linewidth "<solve->CaseFIBOX->isChecked()) { + outFile << "--pdf_size letter\n" ;} } // Legal else if( pdfSize == 1 ) @@ -2196,7 +2334,8 @@ int mainWindow::solve() pdfHeight = 14.0; pdfWidth = 8.5; - outFile << "--pdf_size legal\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--pdf_size legal\n";} } // Tabloid else if( pdfSize == 2 ) @@ -2204,7 +2343,8 @@ int mainWindow::solve() pdfHeight = 17.0; pdfWidth = 11.0; - outFile << "--pdf_size tabloid\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--pdf_size tabloid\n";} } if( tree->pdf->landscapeRadioButton->isChecked() ) { @@ -2215,6 +2355,13 @@ int mainWindow::solve() } bool writeVTK = tree->vtk->vtkGroupBox->isChecked(); + + + //number of processors + int nThreads = tree->solve->numProcSpinBox->value(); + +if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--num_threads " <solve->numProcSpinBox->value(); - - outFile << "--num_threads" + std::to_string(nThreads) + "\n" ; - +} #ifdef NINJAFOAM army = new ninjaArmy(1, useNinjaFoam); // ninjafoam solver #else @@ -2237,7 +2380,6 @@ int mainWindow::solve() { int pointFormat = tree->point->simType; std::vector pointFileList = tree->point->stationFileList; //This is for the new way - std::string pointFile = tree->point->stationFileList[0]; //For Old Format, only can accept 1 file std::vector xStartTime = tree->point->startSeries; //Get the start time from pointInput std::vector xEndTime = tree->point->endSeries; //Get the Stop time from pointInput @@ -2245,76 +2387,141 @@ int mainWindow::solve() bool useTimeList = tree->point->enableTimeseries; //Find out if its a timeseries run or not bool writeStationKML = tree->point->writeStationKmlButton->isChecked(); //Write a kml file bool writeStationCSV = tree->point->writeStationFileButton->isChecked(); //hidden for now - /* - if (tree->point->xWidget != NULL) { + std::vector fullFileListPoint = tree->point->fullFileList; + if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true && tree->solve->CaseFIBOX->isChecked()) { + + // for each file append it to csv + // if any point file is under a wx station folder just copy the entire folder over - otherwise no + + outFile << "--fetch_station true\n"; + outFile << "--fetch_type "<< tree->point->xWidget->getType()<< "\n"; + if (tree->point->xWidget->getType() == "bbox") { + outFile << "--station_buffer " <point->xWidget->getBuffer()<< "\n" ; + outFile << "--station_buffer_units " << tree->point->xWidget->getBufferUnits()<< "\n"; + } + if (tree->point->xWidget->getType() == "stid") { + outFile << "--fetch_station_name " << tree->point->xWidget->getStationIDS() << "\n"; + } + if (tree->point->xWidget->getTimeseries() == false) { + outFile << "--fetch_current_station_data false\n"; + outFile << "--number_time_steps " << std::to_string(numTimeSteps) <<"\n"; + } + else { + outFile << "--fetch_current_station_data true\n"; + } - if (tree->point->xWidget->getBuffer() != "") { - - outFile << "--station_buffer " + tree->point->xWidget->getBuffer().toStdString(); - } - if (tree->point->xWidget->getBufferUnits() != "") { - - outFile << "--station_buffer_units " + tree->point->xWidget->getBufferUnits(); - } - if (tree->point->xWidget->getType() != "") { - - outFile << "--fetch_type " + tree->point->xWidget->getType(); - } + if (writeStationKML) { + + outFile << "--write_wx_station_kml true\n"; + } + else { + outFile << "--write_wx_station_kml false\n"; + + } + if (writeStationCSV) { + outFile << "--write_wx_station_csv true\n"; + } + else { + outFile << "--write_wx_station_csv false\n"; + + } + + } -*/ - outFile << "--fetch_station_name "; + + else if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--fetch_station false\n"; if (useTimeList) { - outFile << "--fetch_current_station_data false"; + outFile << "--fetch_current_station_data false\n"; + + outFile << "--start_year " << xStartTime[0] << "\n"; + outFile << "--start_month " <solve->CaseFIBOX->isChecked()) ) { + + for (std::string & pfile : fullFileListPoint) { + std::vector tokens = split(pfile, "/"); + + if (tokens.size() >= 2) { + std::string secondToLastToken = tokens[tokens.size()-2]; + + std::string pointpath1 = "pointinitialization/" + tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1] ; + std::string pointpath2 = "pointinitialization/" + tokens[tokens.size()-1] ; + if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { + casefile.addFileToZip(zipFilePath, getdir, pointpath1, pfile); + } + else { + casefile.addFileToZip(zipFilePath , getdir, pointpath2, pfile); + } + } + } - outFile << "--start_year" << xStartTime[0] << "\n"; - outFile << "--start_month" < tokens = split(pfile, "/"); + std::string updatedpath = casefile.parse("file", pfile); + if (tokens.size() >= 2) { + + std::string secondToLastToken = tokens[tokens.size()-2]; + if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { + updatedpath = secondToLastToken + "/" + tokens[tokens.size() - 1]; + } + + } - outFile << "--number_time_steps" << std::to_string(numTimeSteps)<<"\n"; + stationCSVFILE << updatedpath << "\n"; + } + stationCSVFILE.close(); + std::string pointpathusual = "pointinitialization/selectedstations.csv"; + casefile.addFileToZip(zipFilePath , getdir, pointpathusual , stationCSVFILEPATH); + + } /* + } * Note that pointFormat is not the same as stationFormat! * * point Format is based on pointInput::directStationTraffic @@ -2338,20 +2545,17 @@ int mainWindow::solve() * in wxStation::getFirstStationLine * */ - + if (pointFormat==0) { CPLDebug("STATION_FETCH","USING OLD FORMAT..."); - pointInitialization::SetRawStationFilename(pointFile); //Note: When testing this, //Only the old format works, so downloaded data, with the date-time column don't yet work! /* right now the only option is the old format */ wxStation::SetStationFormat(wxStation::oldFormat); - std::vector timeList; if(useDiurnal==true || useStability==true) //means that the user is specifying time - { //Get that time and assign it to the simulation - //outFile << "--number_time_steps" + numTimeSteps.toStdString() ; + { //Get that time and assign it to the simulation std::vector xSingleTime = tree->point->diurnalTimeVec; boost::posix_time::ptime singleTime = pointInitialization::generateSingleTimeObject(xSingleTime[0],xSingleTime[1],xSingleTime[2],xSingleTime[3],xSingleTime[4],timeZone); timeList.push_back(singleTime); @@ -2363,7 +2567,8 @@ int mainWindow::solve() } try{ //Try to run windninja - outFile << "--match_points true\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--match_points true\n";} army->makeStationArmy(timeList,timeZone, pointFile, demFile, true,false); } catch(...){ //catch all exceptions and tell the user, prevent segfaults @@ -2395,7 +2600,6 @@ int mainWindow::solve() { formatVec.push_back(wxStation::GetHeaderVersion(pointFileList[i].c_str())); } - if (std::equal(formatVec.begin()+1,formatVec.end(),formatVec.begin())) //Make sure all the header versions are equal, in case one of them gets past all the gui checkss { CPLDebug("STATION_FETCH","HEADER VERSIONS ARE GOOD..."); @@ -2422,7 +2626,8 @@ int mainWindow::solve() try{ //try running with timelist - outFile << "--match_points true\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--match_points true\n";} army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); //setting pointFileList[0] is just for header checks etc } catch(...){ //catch any and all exceptions and tell the user @@ -2453,12 +2658,12 @@ int mainWindow::solve() boost::posix_time::ptime singleTime = pointInitialization::generateSingleTimeObject(xSingleTime[0], xSingleTime[1],xSingleTime[2], xSingleTime[3],xSingleTime[4],timeZone); - - timeList.push_back(singleTime); + timeList.push_back(singleTime); pointInitialization::storeFileNames(pointFileList); try{ //try making the army with current data - outFile << "--match_points true\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--match_points true\n";} army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); } catch(...){ //catch any and all exceptions and tell the user @@ -2499,9 +2704,9 @@ int mainWindow::solve() delete army; return false; } - + + } - if (writeStationKML==true) //Write KMLS for each time step { writeToConsole("Writing Weather Station .kml"); @@ -2514,7 +2719,6 @@ int mainWindow::solve() } } // if (writeStationCSV==true) - const char *csvOpt = CPLGetConfigOption("WRITE_CSV","FALSE"); if(csvOpt!="FALSE") //The only way to write an interpolated CSV is to set a config option { @@ -2527,7 +2731,6 @@ int mainWindow::solve() } const char *metaOpt = CPLGetConfigOption("FETCH_METADATA","FALSE"); - if(metaOpt!="FALSE") //set a config option to get the metadata from the DEM { //There is also a button for this, that is hidden (see stationFetchWidget) writeToConsole("Fetching station metadata for DEM..."); @@ -2536,8 +2739,10 @@ int mainWindow::solve() std::string baseMeta = baseDem+"-metadata"; std::string metaPath = std::string(CPLFormFilename(pathDem.c_str(),baseMeta.c_str(),".csv")); CPLDebug("STATION_FETCH","Saving Metadata to: %s",metaPath.c_str()); - outFile << "--fetch_metadata true\n"; - outFile << "--metadata_filename" << metaPath<< "\n"; + + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--fetch_metadata true\n"; + outFile << "--metadata_filename" << metaPath<< "\n"; } pointInitialization::fetchMetaData(metaPath,demFile,true); } } @@ -2569,30 +2774,43 @@ int mainWindow::solve() progressDialog->cancel(); return false; } - + std::vector times = tree->weather->timeList(); + - std::vector stringTimes; + if ( times.size() > 0 ) { - // Iterate over each element in the vector - for (const auto& time : times) - { - stringTimes.push_back(boost::posix_time::to_iso_string(time.local_time())); // Convert and add to vector - } - - /* This can throw a badForecastFile */ - std::string outstr; - - for (size_t i = 0; i < stringTimes.size(); ++i) - { - outstr += stringTimes[i]; - if (i != stringTimes.size() - 1) { - outstr += "||"; + if (tree->solve->CaseFIBOX->isChecked()) { + std::vector stringTimes; + blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); + + for (const auto& time : times) { + // Convert local_date_time to ptime using the UTC time zone + // Get the local time in the UTC time zone + bpt::ptime pt = time.local_time_in(utc).local_time(); + + // Convert ptime to ISO 8601 string + std::string isoString = bpt::to_iso_string(pt); + stringTimes.push_back(isoString); + } + + std::string outstr; + for (size_t i = 0; i < stringTimes.size(); ++i) + { + outstr += stringTimes[i]; + if (i != stringTimes.size() - 1) { + outstr += "||"; + } + } + + outFile << "--forecast_times " << outstr <<"\n"; + + outFile << "--forecast_filename " << weatherFile << "\n"; + std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); + casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); } } - outFile << "--forecast_times" << outstr <<"\n"; - - outFile << "--forecast_filename" << weatherFile << "\n"; + try { @@ -2629,6 +2847,42 @@ int mainWindow::solve() delete army; return false; } + + //get times for casefile if no times are clicked by user + + if (times.size() == 0 && tree->solve->CaseFIBOX->isChecked()) { + + + std::vector wxtimesfromcasefile = casefile.getWXTIME(); + std::vector stringTimes; + blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); + + for (const auto& time : wxtimesfromcasefile) { + // Convert local_date_time to ptime using the UTC time zone + // Get the local time in the UTC time zone + bpt::ptime pt = time.local_time_in(utc).local_time(); + + // Convert ptime to ISO 8601 string + std::string isoString = bpt::to_iso_string(pt); + stringTimes.push_back(isoString); + } + + std::string outstr; + for (size_t i = 0; i < stringTimes.size(); ++i) + { + outstr += stringTimes[i]; + if (i != stringTimes.size() - 1) { + outstr += "||"; + } + } + + outFile << "--forecast_times " << outstr <<"\n"; + + outFile << "--forecast_filename " << weatherFile << "\n"; + std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); + casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); + } + nRuns = army->getSize(); } @@ -2638,8 +2892,9 @@ int mainWindow::solve() runProgress = new int[nRuns]; //I don't think this is needed anymore std::string outputDir = tree->solve->outputDirectory().toStdString(); - outFile << "--output_path " << outputDir<< "\n" ; - + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--output_path " << outputDir<< "\n" ; + } if( outputDir == "" ) { // This should never happen, so if it does, fix it. throw( "no output directory specified in solve page" ); @@ -2649,6 +2904,9 @@ int mainWindow::solve() for(int i = 0;i < army->getSize(); i++) { + std::string domaininputpath = getdir + "/domainrun" + std::to_string(i) + ".cfg"; + std::ofstream domainRUNS(domaininputpath); + army->setDEM( i, demFile ); #ifdef NINJAFOAM if(caseFile != ""){ @@ -2677,18 +2935,19 @@ int mainWindow::solve() else if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { //get speed - outFile << "--input_speed " <wind->windTable->speed[i]->value()) << "\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_speed " <wind->windTable->speed[i]->value()) << "\n"; } army->setInputSpeed( i, tree->wind->windTable->speed[i]->value(), inputSpeedUnits); //get direction - outFile << "--input_direction " <wind->windTable->dir[i]->value()) <<"\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--input_direction " <wind->windTable->dir[i]->value()) <<"\n"; } army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); army->setInputWindHeight ( i, inHeight, inHeightUnits ); - } //set input output height @@ -2709,31 +2968,33 @@ int mainWindow::solve() if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - outFile << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; - outFile << "--month " <wind->windTable->date[i]->date().month() << "\n"; + domainRUNS << "--month " <wind->windTable->date[i]->date().month() << "\n"; - outFile << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; + domainRUNS << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; - outFile << "--hour " <wind->windTable->time[i]->time().hour() << "\n"; + domainRUNS << "--hour " <wind->windTable->time[i]->time().hour() << "\n"; - outFile << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; - + domainRUNS << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; + } army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), tree->wind->windTable->time[i]->time().hour(), tree->wind->windTable->time[i]->time().minute(), 0, timeZone ); - outFile << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; army->setUniAirTemp( i, tree->wind->windTable->airTemp[i]->value(), tempUnits ); - outFile << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; + if (tree->solve->CaseFIBOX->isChecked()) { + domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; + domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; - outFile << "--cloud_cover_units percent" << "\n" ; - + domainRUNS << "--cloud_cover_units percent" << "\n" ; + } army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -2758,34 +3019,36 @@ int mainWindow::solve() { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - outFile << "--year " <wind->windTable->date[i]->date().year() <<"\n"; - - outFile << "--month " <wind->windTable->date[i]->date().month() <<"\n"; - - outFile << "--day " <wind->windTable->date[i]->date().day() <<"\n"; + if (tree->solve->CaseFIBOX->isChecked()) { - outFile << "--hour " << - tree->wind->windTable->time[i]->time().hour()<< "\n"; + domainRUNS << "--year " <wind->windTable->date[i]->date().year() <<"\n"; - outFile << "--minute "<< tree->wind->windTable->time[i]->time().minute()<<"\n"; - + domainRUNS << "--month " <wind->windTable->date[i]->date().month() <<"\n"; + domainRUNS << "--day " <wind->windTable->date[i]->date().day() <<"\n"; + + domainRUNS << "--hour " << + tree->wind->windTable->time[i]->time().hour()<< "\n"; + + domainRUNS << "--minute "<< tree->wind->windTable->time[i]->time().minute()<<"\n"; + + } army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), tree->wind->windTable->time[i]->time().hour(), tree->wind->windTable->time[i]->time().minute(), 0, timeZone ); - army->setUniAirTemp( i, tree->wind->windTable->airTemp[i]->value(), tempUnits ); - outFile << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value() << "\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value() << "\n"; - outFile << "--uni_air_temp " <wind->windTable->airTemp[i]->value() << "\n"; - outFile << "--cloud_cover_units percent"<< "\n"; - + domainRUNS << "--uni_air_temp " <wind->windTable->airTemp[i]->value() << "\n"; + domainRUNS << "--cloud_cover_units percent\n"; + } army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -2796,30 +3059,32 @@ int mainWindow::solve() army->setPosition( i, GDALCenterLat, GDALCenterLon ); } } - army->setStabilityFlag( i, useStability ); //set mesh stuff if( customMesh ) { - army->setMeshResolution( i, meshRes, meshUnits ); } else { #ifdef NINJAFOAM if(useNinjaFoam){ - if(ninjafoamMeshChoice == WindNinjaInputs::coarse){ - outFile << "--mesh_count 25000" << "\n"; - } - else if(meshChoice == WindNinjaInputs::medium){ - outFile << "--mesh_count 50000" << "\n"; + + if (tree->solve->CaseFIBOX->isChecked()) { + if(ninjafoamMeshChoice == WindNinjaInputs::coarse){ + outFile << "--mesh_count 25000\n"; + } + else if(meshChoice == WindNinjaInputs::medium){ + outFile << "--mesh_count 50000\n"; + } + else if(meshChoice == WindNinjaInputs::fine){ + outFile << "--mesh_count 100000\n"; } - else if(meshChoice == WindNinjaInputs::fine){ - outFile << "--mesh_count 100000" << "\n"; } army->setMeshCount( i, ninjafoamMeshChoice ); - outFile << "--number_of_iterations 300" <<"\n"; + if (tree->solve->CaseFIBOX->isChecked()) { + outFile << "--number_of_iterations 300\n";} army->setNumberOfIterations( i, 300); } else @@ -2839,7 +3104,7 @@ int mainWindow::solve() //set number of cpus... //army.setnumberCPUs(1); - + army->setGoogOutFlag (i,writeGoogle); army->setGoogLineWidth (i,vectorWidth); army->setGoogResolution (i,googleRes,googleUnits); @@ -2867,19 +3132,35 @@ int mainWindow::solve() //army.setOutputFilenames(); army->setNinjaComNumRuns( i, nRuns ); - } + + //add different input to config + domainRUNS.close(); + + std::string domainaveragepath = "DomainAverage/run " + std::to_string(i) + ".cfg"; + std::string domainaveragedeletion = "domainrun" + std::to_string(i) + ".cfg"; + + if (tree->solve->CaseFIBOX->isChecked()) { + if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { + casefile.addFileToZip(zipFilePath, getdir, domainaveragepath, domaininputpath ); + } + + casefile.deleteFileFromPath(getdir, domainaveragedeletion ); + } + } + //set Casefile Directory and Input - std::string getfileName = casefile.parse("file", inputFileName.toStdString()); - std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; - casefile.setdir(getdir); - casefile.setzip(zipFilePath); - outFile.close(); - - casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); + + if (tree->solve->CaseFIBOX->isChecked()) { + outFile.close(); + casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); + + casefile.deleteFileFromPath(getdir, "selectedstations.csv"); + } + army->set_writeFarsiteAtmFile( writeAtm && writeFb ); @@ -3320,8 +3601,6 @@ int mainWindow::checkSpdDirItem() } return status; } - - int mainWindow::checkPointItem() { eInputStatus status = blue; diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index ea40d867..bc3a9b5d 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -47,6 +47,9 @@ #include #include #include +#include +#include + #include "gdal_priv.h" #include "ogr_srs_api.h" @@ -67,7 +70,6 @@ #include "setconfigdialog.h" - class mainWindow : public QMainWindow { Q_OBJECT @@ -87,7 +89,7 @@ class mainWindow : public QMainWindow QTimer *timer; - int *runProgress; + int *runProgress; int totalProgress; std::vector progressLog; @@ -184,14 +186,16 @@ class mainWindow : public QMainWindow void treeDoubleClick(QTreeWidgetItem *item, int column); bool getLatLon(); - + void test(); + int solve(); void cancelSolve(); int countRuns(); void openOutputPath(); +std::vector split(const std::string &s, const std::string &delimiter) ; //functions for checking inputItems int checkInputItem(); int checkSurfaceItem(); diff --git a/src/gui/pointInput.cpp b/src/gui/pointInput.cpp index 4e744ea9..3de81b80 100644 --- a/src/gui/pointInput.cpp +++ b/src/gui/pointInput.cpp @@ -37,6 +37,7 @@ static int wxStationFormat; pointInput::pointInput( QWidget *parent ) : QWidget( parent ) { + xWidget = NULL; pointGroupBox = new QGroupBox( "Point Initialization", this ); pointGroupBox->setCheckable( true ); pointGroupBox->setChecked(false); @@ -90,7 +91,7 @@ pointInput::pointInput( QWidget *parent ) : QWidget( parent ) sfModel = new QDirModel(this); //Creates the directory model sfModel->setReadOnly(true); //probably can be true, but i don't know sfModel->setSorting(QDir::Time); //Sort by time created - + treeView = new QTreeView(this); //Creates the box where the sfModel goes treeView->setVisible(true); treeView->setModel(sfModel); //Sets the model to the thing above @@ -271,6 +272,39 @@ pointInput::~pointInput() } + + + +void pointInput::collectAllIndexes(const QModelIndex &parent, std::vector &allIndexes) const { + for (int row = 0; row < sfModel->rowCount(parent); ++row) { + QModelIndex index = sfModel->index(row, 0, parent); + allIndexes.push_back(index); + if (sfModel->isDir(index)) { + collectAllIndexes(index, allIndexes); // Recursively collect child indexes + } + } +} + +void pointInput::generateFullFileList() { + std::vector allIndexes; + std::vector fileList; + + // Collect all indexes starting from the root index + QModelIndex rootIndex = treeView->rootIndex(); + + collectAllIndexes(rootIndex, allIndexes); + + for (const QModelIndex &index : allIndexes) { + if (!sfModel->isDir(index)) { // Check if it is a file + QString filePath = sfModel->filePath(index); + fileList.push_back(filePath.toStdString()); + } + } + + fullFileList = fileList; +} + + /** * @brief pointInput::readStationFiles * Reads the files on disk that the user selects @@ -302,6 +336,8 @@ void pointInput::readStationFiles(const QItemSelection &x ,const QItemSelection CPLDebug("STATION_FETCH","========================================"); CPLDebug("STATION_FETCH","NUMBER OF SELECTED STATIONS: %i",idx0.count()); + generateFullFileList(); + for(int i=0;ifileInfo(idx0[i]).isDir()==true) //If its a directory, make it so that it can't be selected @@ -1016,4 +1052,4 @@ void pointInput::checkForModelData() sfModel->setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); //QDir::Dir specifies to add filters to directories treeView->setRootIndex(sfModel->index(wd.absolutePath())); treeView->resizeColumnToContents(0); -} +} \ No newline at end of file diff --git a/src/gui/pointInput.h b/src/gui/pointInput.h index b920809e..7d438110 100644 --- a/src/gui/pointInput.h +++ b/src/gui/pointInput.h @@ -78,6 +78,7 @@ class pointInput : public QWidget QString demFileName; QString stationFileName; std::vector stationFileList; + std::vector fullFileList; std::vector stationFileTypes; int simType; bool pointGo; @@ -159,6 +160,10 @@ class pointInput : public QWidget void setOneStepTimeseries(); private slots: + + void generateFullFileList() ; + void collectAllIndexes(const QModelIndex &parent, std::vector &allIndexes) const; + void readStationFiles(const QItemSelection &x ,const QItemSelection &y); void selChanged(const QItemSelection &x ,const QItemSelection &y); //Test Function void setInputFile( QString file ); diff --git a/src/gui/solvePage.cpp b/src/gui/solvePage.cpp index 7408e358..0fc9d60c 100644 --- a/src/gui/solvePage.cpp +++ b/src/gui/solvePage.cpp @@ -76,12 +76,17 @@ solvePage::solvePage(QWidget *parent) : QWidget(parent) openOutputPathButton->setIcon( QIcon( ":folder.png" ) ); openOutputPathButton->setDisabled( true ); + CaseFIBOX = new QCheckBox(tr("Generate a Casefile for this run"), this); + CaseFIBOX->setChecked(true); + connect(CaseFIBOX, SIGNAL(toggled(bool)), this, SLOT(onCasefileCheckBoxToggled(bool))); + layout = new QVBoxLayout; layout->addWidget(availProcLabel); pageLayout = new QHBoxLayout; pageLayout->addWidget(numProcLabel); pageLayout->addWidget(numProcSpinBox); + pageLayout->addWidget(CaseFIBOX); pageLayout->addWidget(solveToolButton); pageLayout->addStretch(); @@ -111,6 +116,10 @@ void solvePage::chooseOutputDir() { outputDirLineEdit->setText( dir ); } +void solvePage::onCasefileCheckBoxToggled(bool checked) { +} + + QString solvePage::outputDirectory() { return outputDirLineEdit->text(); } diff --git a/src/gui/solvePage.h b/src/gui/solvePage.h index 1f8d61b9..20425633 100644 --- a/src/gui/solvePage.h +++ b/src/gui/solvePage.h @@ -37,6 +37,7 @@ #include #include +#include #include #ifdef _OPENMP @@ -58,7 +59,7 @@ class solvePage : public QWidget QString availProcString; QLabel *availProcLabel; QSpinBox *numProcSpinBox; - + QCheckBox *CaseFIBOX; QLabel *outputDirLabel; QLineEdit *outputDirLineEdit; QToolButton *outputDirToolButton; @@ -77,6 +78,7 @@ public slots: private slots: void chooseOutputDir(); + void onCasefileCheckBoxToggled(bool checked); }; #endif /* SOLVEPAGE_H */ diff --git a/src/gui/stationFetchWidget.cpp b/src/gui/stationFetchWidget.cpp index d7933312..99fe1c19 100644 --- a/src/gui/stationFetchWidget.cpp +++ b/src/gui/stationFetchWidget.cpp @@ -47,7 +47,7 @@ stationFetchWidget::stationFetchWidget(QWidget *parent) currentBox->setVisible(false); fetchMetaButton->setVisible(false); //Hide the metadata button from the gui - + pressedexecute = false; stationFetchProgress = new QProgressDialog(this); //Sets up a mediocre progress bar that kind of works stationFetchProgress->setWindowModality(Qt::ApplicationModal); stationFetchProgress->setAutoReset(false); //Displays how far along the download process is @@ -196,6 +196,7 @@ void stationFetchWidget::updateFetchProgress() */ void stationFetchWidget::executeFetchStation() { + setActuallyPressed(true); stationFetchProgress->setLabelText("Downloading Station Data!"); stationFetchProgress->setRange(0,0); //make it bounce back and forth stationFetchProgress->setCancelButtonText("Cancel"); @@ -256,6 +257,53 @@ std::string stationFetchWidget::demButcher()//Cleans up the DEM for use in the d // std::string demBetter=demRaw.substr(0,lastDot)+"/"; return demPath; } + +bool stationFetchWidget::getActuallyPressed() { + return pressedexecute; +} +void stationFetchWidget::setActuallyPressed(bool pressed) { + pressedexecute = pressed; +} + + +std::string stationFetchWidget::getStationIDS() { + return removeWhiteSpace(idLine->text().toStdString()); +} + +int stationFetchWidget::getBuffer() { + if (bufferSpin->text().toDouble() == 0) { + return 0; + } + return bufferSpin->text().toDouble(); +} + + + +std::string stationFetchWidget::getBufferUnits() { + return buffUnits->currentText().toStdString(); +} + + +bool stationFetchWidget::getTimeseries() { + if (timeLoc->currentIndex() == 1) { + return false; + } + else { + return true; + } +} + +std::string stationFetchWidget::getType() { + if (geoLoc->currentIndex() == 0) { + return "bbox"; + } + else { + return "stid"; + } +} + + + /** * @brief stationFetchWidget::fetchStation * Fetches data from the Mesowest API based on GUI request @@ -278,7 +326,7 @@ int stationFetchWidget::fetchStation() std::string demUse=demButcher(); std::string stationPathName; CPLDebug("STATION_FETCH","USING DEM: %s",demUse.c_str()); - + int terrainPart=geoLoc->currentIndex(); int timePart=timeLoc->currentIndex(); @@ -341,13 +389,14 @@ int stationFetchWidget::fetchStation() bufferUnits=buffUnits->currentText().toStdString(); fetchNow=true; - //Set the Station Buffer + //Set the Station Buffer + pointInitialization::setStationBuffer(buffer,bufferUnits); //Generates the directory to store the file names, because current data is on, don't specify time zone stationPathName=pointInitialization::generatePointDirectory(demFileName.toStdString(),demUse,true); pointInitialization::SetRawStationFilename(stationPathName); + result = pointInitialization::fetchStationFromBbox(demFileName.toStdString(),eTimeList,tzString.toStdString(),fetchNow); - CPLDebug("STATION_FETCH","Return: %i",result); } //DEM and Time series @@ -420,7 +469,6 @@ int stationFetchWidget::fetchStation() int sY,sMo,sD,sH,sMi; int eY,eMo,eD,eH,eMi; int numSteps=10; //make up a number for now.... It really doesn't matter at this point - std::string StartTime=startEdit->text().toStdString(); std::string EndTime=endEdit->text().toStdString(); diff --git a/src/gui/stationFetchWidget.h b/src/gui/stationFetchWidget.h index b8dbb815..998c479e 100644 --- a/src/gui/stationFetchWidget.h +++ b/src/gui/stationFetchWidget.h @@ -47,6 +47,8 @@ #include "ui_stationFetchWidget.h" #include "GoogleMapsInterface.h" +#include +#include #include "pointInitialization.h" #ifndef PI @@ -67,8 +69,15 @@ class stationFetchWidget : public QWidget, private Ui::stationFetchWidget QString tzString; void updatetz(QString tz); void fixTime(); - std::string removeWhiteSpace(std::string str); - + std::string removeWhiteSpace(std::string str); + void setActuallyPressed(bool pressed); + bool getActuallyPressed(); + std::string getStationIDS(); + int getBuffer(); + std::string getBufferUnits(); + bool getTimeseries(); + std::string getType(); + protected: void closeEvent(QCloseEvent *event); @@ -93,7 +102,7 @@ class stationFetchWidget : public QWidget, private Ui::stationFetchWidget //Progress Bar Stuff QProgressDialog *stationFetchProgress; QFutureWatcher stationFutureWatcher; - + bool pressedexecute; friend class pointInput; }; diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 8454fc5f..8221765e 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -2,8 +2,12 @@ std::string CaseFile::zipfilename = ""; std::string CaseFile::directory = ""; - +bool CaseFile::zipalreadyopened = false; std::mutex zipMutex; +std::vector CaseFile::timesforWX; +std::vector CaseFile::boundingboxarr; +bool CaseFile::downloadedfromdem; +std::string CaseFile::elevsource; CaseFile::CaseFile() { } @@ -54,6 +58,8 @@ bool CaseFile::lookfordate(const std::string& date) { } + + std::string CaseFile::parse(const std::string& type, const std::string& path) { size_t found = path.find_last_of("/"); if (found != std::string::npos) { @@ -70,98 +76,89 @@ std::string CaseFile::parse(const std::string& type, const std::string& path) { void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath) { - // Enable CPL logging - std::lock_guard lock(zipMutex); // for multithreading issue?? not sure I think i busted it + // CPL logging enabled here + std::lock_guard lock(zipMutex); // for multithreading issue CPLSetConfigOption("CPL_DEBUG", "ON"); - std::cout << "ZIP File Path: " << zipFilePath << std::endl; - std::cout << "Directory Path: " << dirPath << std::endl; - std::cout << "File to Add Path: " << usrlocalpath << std::endl; - std::cout << "File to Add: " << fileToAdd << std::endl; + try { + bool foundzip = lookforzip(zipFilePath, dirPath); + + if (foundzip) { + std::ifstream infile(zipFilePath); + if (!infile.good()) { + CPLDebug("ZIP", "ZIP file does not exist: %s", zipFilePath.c_str()); + return; + } + } - bool foundzip = lookforzip(zipFilePath, dirPath); - std::cout << "Found ZIP: " << foundzip << std::endl; + zipFile zip; + if (!foundzip) { + zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_CREATE); + } else { + zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_ADDINZIP); + } - if (foundzip) { - std::ifstream infile(zipFilePath); - if (!infile.good()) { - std::cerr << "ZIP file does not exist: " << zipFilePath << std::endl; + if (zip == NULL) { + CPLDebug("ZIP", "Could not open ZIP: %s", zipFilePath.c_str()); return; } - } - zipFile zip; - if (!foundzip) { - zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_CREATE); - std::cout << "Creating new ZIP file: " << zipFilePath << std::endl; - } else { - zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_ADDINZIP); - std::cout << "Appending to existing ZIP file: " << zipFilePath << std::endl; - } + zip_fileinfo zi = {0}; + if (cpl_zipOpenNewFileInZip(zip, fileToAdd.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { + CPLDebug("ZIP", "Could not open new file in ZIP: %s", fileToAdd.c_str()); + cpl_zipClose(zip, nullptr); + return; + } - if (zip == NULL) { - std::cerr << "Failed to open ZIP file: " << zipFilePath << std::endl; - CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open ZIP file %s", zipFilePath.c_str()); - const char* errMsg = CPLGetLastErrorMsg(); - std::cerr << "GDAL Error: " << errMsg << std::endl; - return; - } + VSILFILE *file = VSIFOpenL(usrlocalpath.c_str(), "rb"); + if (file == nullptr) { + CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", usrlocalpath.c_str()); + cpl_zipCloseFileInZip(zip); + cpl_zipClose(zip, nullptr); + return; + } - zip_fileinfo zi = {0}; - if (cpl_zipOpenNewFileInZip(zip, fileToAdd.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { - std::cerr << "Could not open new file in ZIP: " << fileToAdd << std::endl; - CPLError(CE_Failure, CPLE_FileIO, "Could not open new file in ZIP %s", fileToAdd.c_str()); - cpl_zipClose(zip, nullptr); - return; - } + VSIFSeekL(file, 0, SEEK_END); + vsi_l_offset fileSize = VSIFTellL(file); + VSIFSeekL(file, 0, SEEK_SET); - VSILFILE *file = VSIFOpenL(usrlocalpath.c_str(), "rb"); - if (file == nullptr) { - std::cerr << "Could not open file for reading with VSIL: " << usrlocalpath << std::endl; - CPLError(CE_Failure, CPLE_FileIO, "Could not open file for reading with VSIL %s", usrlocalpath.c_str()); - cpl_zipCloseFileInZip(zip); - cpl_zipClose(zip, nullptr); - return; - } + char *data = (char*)CPLMalloc(fileSize); + if (data == nullptr) { + CPLDebug("Memory", "Failed to allocate memory for file data."); + VSIFCloseL(file); + cpl_zipCloseFileInZip(zip); + cpl_zipClose(zip, nullptr); + return; + } - VSIFSeekL(file, 0, SEEK_END); - vsi_l_offset fileSize = VSIFTellL(file); - VSIFSeekL(file, 0, SEEK_SET); + if (VSIFReadL(data, 1, fileSize, file) != fileSize) { + CPLDebug("FileRead", "Failed to read file contents: %s", fileToAdd.c_str()); + CPLFree(data); + VSIFCloseL(file); + cpl_zipCloseFileInZip(zip); + cpl_zipClose(zip, nullptr); + return; + } - char *data = (char*)CPLMalloc(fileSize); - if (data == nullptr) { - std::cerr << "Failed to allocate memory for file data." << std::endl; - CPLError(CE_Failure, CPLE_OutOfMemory, "Failed to allocate memory for file data."); - VSIFCloseL(file); - cpl_zipCloseFileInZip(zip); - cpl_zipClose(zip, nullptr); - return; - } + if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) { + CPLDebug("ZIP", "Error writing data to ZIP file: %s", fileToAdd.c_str()); + } - if (VSIFReadL(data, 1, fileSize, file) != fileSize) { - std::cerr << "Failed to read file contents: " << fileToAdd << std::endl; - CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents %s", fileToAdd.c_str()); CPLFree(data); VSIFCloseL(file); cpl_zipCloseFileInZip(zip); - cpl_zipClose(zip, nullptr); - return; - } - if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) { - std::cerr << "Error writing data to ZIP file: " << fileToAdd << std::endl; - CPLError(CE_Failure, CPLE_FileIO, "Error writing data to ZIP file %s", fileToAdd.c_str()); - } - - CPLFree(data); - VSIFCloseL(file); - cpl_zipCloseFileInZip(zip); + if (cpl_zipClose(zip, nullptr) != ZIP_OK) { + CPLDebug("ZIP", "Error closing ZIP file: %s", zipFilePath.c_str()); + } - if (cpl_zipClose(zip, nullptr) != ZIP_OK) { - std::cerr << "Error closing ZIP file" << std::endl; - CPLError(CE_Failure, CPLE_FileIO, "Error closing ZIP file %s", zipFilePath.c_str()); + } catch (const std::exception& e) { + CPLDebug("Exception", "Caught exception: %s", e.what()); + CPLError(CE_Failure, CPLE_AppDefined, "Exception caught: %s", e.what()); + } catch (...) { + CPLDebug("Exception", "Caught unknown exception."); + CPLError(CE_Failure, CPLE_AppDefined, "Caught unknown exception."); } - std::cout << "File added to ZIP: " << fileToAdd << std::endl; } @@ -202,18 +199,65 @@ void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filenam CSLDestroy(papszDir); } } - void CaseFile::setdir(std::string dir) { - directory = dir; - } - std::string CaseFile::getzip() { - return zipfilename; - } - void CaseFile::setzip(std::string zip) { - zipfilename = zip; - } - std::string CaseFile::getdir() { - return directory; +void CaseFile::setdir(std::string dir) { + directory = dir; +} + +std::string CaseFile::getzip() { + return zipfilename; +} + +void CaseFile::setzip(std::string zip) { + zipfilename = zip; +} + +std::string CaseFile::getdir() { + return directory; +} +void CaseFile::setZipOpen(bool zipopen) { + if (zipopen) { + zipalreadyopened = true; } + else { + zipalreadyopened = false; + } +} + +bool CaseFile::getZipOpen() { + return zipalreadyopened; +} + +void CaseFile::setTimeWX (std::vector timeList ) { + timesforWX = timeList; +} + +std::vector CaseFile::getWXTIME () { + return timesforWX; +} + + +void CaseFile::setBoundingBox ( std::vector boundingboxarrr) { + boundingboxarr = boundingboxarrr; +} + +void CaseFile::setElevSource (std::string elevsourcee ) { + elevsource = elevsourcee; +} + +void CaseFile::setDownloadedFromDEM (bool downloadedfromdemm) { + downloadedfromdem = downloadedfromdemm; +} + +std::string CaseFile::getElevSource () { + return elevsource; +} +bool CaseFile::getDownloadedFromDEM () { + return downloadedfromdem; +} + +std::vector CaseFile::getBoundingBox () { + return boundingboxarr; +} diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 17a5e05c..c20f2188 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -41,34 +41,56 @@ #include #include #include -#include "cpl_error.h" +#include class CaseFile { private: static std::string zipfilename; - static std::string directory; + static std::string directory; + static bool zipalreadyopened; + + static std::vector timesforWX; + static std::vector boundingboxarr; + static bool downloadedfromdem; + static std::string elevsource; public: CaseFile(); -void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath); + void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath); + void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); bool lookforzip(const std::string& zipFilePath, const std::string& directory); bool isCfgFile(const std::string& filePath); bool isVTKFile(const std::string& filePath); -std::string parse(const std::string& type, const std::string& path) ; -std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); -bool lookfordate(const std::string& date) ; + std::string parse(const std::string& type, const std::string& path) ; + std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); + bool lookfordate(const std::string& date) ; + + std::string getTime(); + std::string getdir() ; + void setdir(std::string dir); + + std::string getzip () ; + void setzip(std::string zip); + + void setZipOpen(bool zipopen); + bool getZipOpen(); + void setTimeWX(std::vector timeList) ; + + std::vector getWXTIME() ; + + void setBoundingBox ( std::vector boundingboxarrr); -std::string getTime(); -std::string getdir() ; - void setdir(std::string dir); + static void setElevSource (std::string elevsourcee ); - std::string getzip () ; - void setzip(std::string zip); + void setDownloadedFromDEM (bool downloadedfromdemm) ; + std::string getElevSource () ; + bool getDownloadedFromDEM () ; + std::vector CaseFile::getBoundingBox (); }; \ No newline at end of file diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 2a21e276..b831241f 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -137,6 +137,21 @@ const std::string* get_checked_elevation_file (po::variables_map& vm) } +//split for point initialization in casefile + +std::vector split(const std::string &s, const std::string &delimiter) { + std::vector tokens; + size_t start = 0; + size_t end = s.find(delimiter); + while (end != std::string::npos) { + tokens.push_back(s.substr(start, end - start)); + start = end + delimiter.length(); + end = s.find(delimiter, start); + } + tokens.push_back(s.substr(start, end)); + return tokens; +} + /** * Command line implementation (CLI) of WindNinja. Can be run using command line args or @@ -220,6 +235,7 @@ int windNinjaCLI(int argc, char* argv[]) // config file po::options_description config("Simulation options"); config.add_options() + ("write_casefile", po::value()->default_value(true), "generate a casefile of the run which will allow a history of your input and output") ("num_threads", po::value()->default_value(1), "number of threads to use during simulation") ("elevation_file", po::value(), "input elevation path/filename (*.asc, *.lcp, *.tif, *.img)") ("fetch_elevation", po::value(), "download an elevation file from an internet server and save to path/filename") @@ -447,60 +463,83 @@ int windNinjaCLI(int argc, char* argv[]) } } //helper for casefile output of CLI - CaseFile casefile; - std::string getdir = casefile.parse( "directory", vm["elevation_file"].as()); - - std::string inputpath = getdir + "/config.cfg"; + + if (vm["write_casefile"].as() == true) { + CaseFile casefile; + std::string getdir = casefile.parse( "directory", vm["elevation_file"].as()); - std::ofstream outFile(inputpath); - if (!outFile) { - cerr << "Error: Could not open the file for writing!" << endl; - return; - } - - for (const auto& pair : vm) { - const std::string& option_name = pair.first; - const po::variable_value& option_value = pair.second; - - outFile << "--" << option_name << " "; - - try { - if (option_value.value().type() == typeid(int)) { - outFile << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(bool)) { - outFile << std::boolalpha << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(std::string)) { - outFile << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(double)) { - outFile << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(std::vector)) { - const auto& vec = option_value.as>(); - for (const auto& str : vec) { - outFile << str << " "; + std::string inputpath = getdir + "/config.cfg"; + + std::ofstream outFile(inputpath); + if (!outFile) { + cerr << "Error: Could not open the file for writing!" << endl; + return; + } + + for (const auto& pair : vm) { + const std::string& option_name = pair.first; + const po::variable_value& option_value = pair.second; + + outFile << "--" << option_name << " "; + + try { + if (option_value.value().type() == typeid(int)) { + outFile << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(bool)) { + outFile << std::boolalpha << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(std::string)) { + outFile << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(double)) { + outFile << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(std::vector)) { + const auto& vec = option_value.as>(); + for (const auto& str : vec) { + outFile << str << " "; + } + outFile << std::endl; + } else { + outFile << "Unknown type" << std::endl; } - outFile << std::endl; - } else { - outFile << "Unknown type" << std::endl; + } catch (const boost::bad_any_cast& e) { + outFile << "Bad cast: " << e.what() << std::endl; } - } catch (const boost::bad_any_cast& e) { - outFile << "Bad cast: " << e.what() << std::endl; } - } - - // This flush is actually optional because close() will flush automatically - - std::string getfileName = casefile.parse("file", vm["elevation_file"].as()); - std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; - casefile.setdir(getdir); - casefile.setzip(zipFilePath); - outFile.flush(); - outFile.close(); - - casefile.addFileToZip(zipFilePath, getdir, getfileName, vm["elevation_file"].as()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); - + // This flush is actually optional because close() will flush automatically + + std::string getfileName = casefile.parse("file", vm["elevation_file"].as()); + + std::string getconfigname = casefile.parse("file", vm["config_file"].as()); + + std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; + casefile.setZipOpen(true); + casefile.setdir(getdir); + casefile.setzip(zipFilePath); + outFile.flush(); + outFile.close(); + casefile.addFileToZip(zipFilePath, getdir, getconfigname, vm["config_file"].as()); + casefile.addFileToZip(zipFilePath, getdir, getfileName, vm["elevation_file"].as()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); + if (vm.count("forecast_filename")) { + std::string getweatherFileName = "weatherfile/" + casefile.parse("file", vm["forecast_filename"].as()); + casefile.addFileToZip(zipFilePath, getdir, getweatherFileName, vm["forecast_filename"].as()); + } + if (vm.count("wx_station_filename")) { + std::vector tokens = split(vm["wx_station_filename"].as(), "/"); + std::string getpointFileName = casefile.parse("file", vm["wx_station_filename"].as()); + + if (tokens.size() >= 2) { + std::string secondToLastToken = tokens[tokens.size()-2]; + if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { + getpointFileName = secondToLastToken + "/" + tokens[tokens.size() - 1]; + } + + } + + casefile.addFileToZip(zipFilePath, getdir, getpointFileName, vm["wx_station_filename"].as()); + } + } if (vm.count("help")) { cout << visible << "\n"; return 0; @@ -767,6 +806,7 @@ int windNinjaCLI(int argc, char* argv[]) elevation_file = new string(new_elev); } + #endif //EMISSIONS if(vm.count("north") || vm.count("south") || @@ -1185,6 +1225,7 @@ int windNinjaCLI(int argc, char* argv[]) vm["fetch_current_station_data"].as()); // stationPathName="blank"; pointInitialization::SetRawStationFilename(stationPathName); //Set this for fetching + std::cout << stationPathName << std::endl; //so that the fetchStationData function knows where to save the data option_dependency(vm,"fetch_station","fetch_type"); if (vm["fetch_type"].as()=="bbox") //Get data from Bounding Box diff --git a/src/ninja/cli.h b/src/ninja/cli.h index 14d79c24..a6a2dea3 100644 --- a/src/ninja/cli.h +++ b/src/ninja/cli.h @@ -60,6 +60,8 @@ void option_dependency(const po::variables_map& vm, const char* for_what, const void verify_option_set(const po::variables_map& vm, const char* optn); +std::vector split(const std::string &s, const std::string &delimiter); + // this should be used instead of direct 'variables_map["key"].as()' calls since otherwise a single typo // in the key literal results in undefined behavior that can corrupt memory miles away. // Alternatively keys could be defined/used as constants to catch this at compile time diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 33e18817..aec91ff8 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2794,10 +2794,6 @@ void ninja::setUvGrids (AsciiGrid& angGrid, AsciiGrid& velGrid, } } -/**Writes output files. - * Writes VTK, FARSITE ASCII Raster, text comparison, shape, and kmz output files. - */ - @@ -2813,6 +2809,10 @@ std::string ninja::converttimetostd(const boost::local_time::local_date_time& ni } +/**Writes output files. + * Writes VTK, FARSITE ASCII Raster, text comparison, shape, and kmz output files. + */ + void ninja::writeOutputFiles() { set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); @@ -2828,41 +2828,38 @@ void ninja::writeOutputFiles() } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "binary";//"binary";//"ascii"; - volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); CaseFile casefile; - std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", input.volVTKFile); - std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); - std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); - - std::string timestr = ""; - std:: string getlocaltime = casefile.getTime(); - - //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; - if (input.ninjaTime.is_not_a_date_time()) { - timestr = getlocaltime; - } - else { - timestr = converttimetostd(input.ninjaTime); - - } - std::cout << timestr << std::endl; + + if (casefile.getZipOpen()) { + std::string directoryPath = get_outputPath(); + std::string normfile = casefile.parse("file", input.volVTKFile); + std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); + std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); + + std::string timestr = ""; + std:: string getlocaltime = casefile.getTime(); + + //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; + if (input.ninjaTime.is_not_a_date_time()) { + timestr = getlocaltime; + } + else { - std::string getfileName = casefile.parse("file", input.dem.fileName); + timestr = converttimetostd(input.ninjaTime); - std::string zipFilePath = casefile.getzip(); - std::cout << zipFilePath << std::endl; - std::cout << directoryPath << std::endl; + } + + std::string getfileName = casefile.parse("file", input.dem.fileName); - std::cout << input.volVTKFile << std::endl; - std::cout << normfile << std::endl; + std::string zipFilePath = casefile.getzip(); + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); - casefile.deleteFileFromPath(directoryPath , normfile); - casefile.deleteFileFromPath(directoryPath , surfFile); + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + casefile.deleteFileFromPath(directoryPath , normfile); + casefile.deleteFileFromPath(directoryPath , surfFile); + } } catch (exception& e) { @@ -4828,12 +4825,12 @@ void ninja::set_outputPath(std::string path) ** stub, we are using GenerateTempFile to be cross platform. We are just ** using the stub/basename instead of the whole path. */ - const char *pszTmpName = CPLGetBasename(CPLGenerateTempFilename(0)); const char *pszTestPath = CPLFormFilename(path.c_str(), pszTmpName, 0); int nRet; if( VSI_ISDIR( sStat.st_mode ) ){ + //see if we can write to this path nRet = VSIMkdir(pszTestPath, 0777); if(nRet == 0){ VSIRmdir(pszTestPath); diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index ad6c164d..c218b622 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -59,6 +59,7 @@ #include "cpl_string.h" #include "ninja_conv.h" + #include "casefile.h" #include "constants.h" #include "ascii_grid.h" @@ -480,9 +481,8 @@ class ninja void computeUVWField(); void prepareOutput(); bool matched(int iter); - - std::string converttimetostd(const boost::local_time::local_date_time& ninjaTime) ; + void writeOutputFiles(); void deleteDynamicMemory(); From badb4e10fadc39ccb355e90667da83d96648ae14 Mon Sep 17 00:00:00 2001 From: Rui Date: Tue, 17 Dec 2024 09:21:04 -0500 Subject: [PATCH 09/35] scrape3dvtk for ninjafoam --- src/ninja/ninjafoam.cpp | 55 ++++++++++++++++++++++++++++++++++++++++- src/ninja/ninjafoam.h | 5 +++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 709694fc..32e540a0 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2656,6 +2656,25 @@ void NinjaFoam::WriteOutputFiles() } + +const std::string NinjaFoam::get_outputPath() const +{ + return input.outputPath; +} + +std::string NinjaFoam::converttimetostdfoam(const boost::local_time::local_date_time& ninjaTime) { + std::ostringstream ss; + + ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); + + ss << ninjaTime; + + std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); + return result; +} + + + void NinjaFoam::writeMassMeshVtkOutput() { @@ -2692,7 +2711,41 @@ void NinjaFoam::writeMassMeshVtkOutput() } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; - volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); + std::cerr << "hello" << std::endl; + + volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); + CaseFile casefile; + + if (casefile.getZipOpen()) { + std::string directoryPath = get_outputPath(); + std::string normfile = casefile.parse("file", input.volVTKFile); + std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); + std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); + + std::string timestr = ""; + std:: string getlocaltime = casefile.getTime(); + + //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; + if (input.ninjaTime.is_not_a_date_time()) { + timestr = getlocaltime; + } + else { + + timestr = converttimetostdfoam(input.ninjaTime); + + } + + std::string getfileName = casefile.parse("file", input.dem.fileName); + + std::string zipFilePath = casefile.getzip(); + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + casefile.deleteFileFromPath(directoryPath , normfile); + casefile.deleteFileFromPath(directoryPath , surfFile); + } + } catch (exception& e) { input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); } catch (...) { diff --git a/src/ninja/ninjafoam.h b/src/ninja/ninjafoam.h index 2aba8b1d..86325515 100644 --- a/src/ninja/ninjafoam.h +++ b/src/ninja/ninjafoam.h @@ -80,6 +80,9 @@ class NinjaFoam : public ninja virtual double get_meshResolution(); static int GenerateFoamDirectory(std::string demName); static void SetFoamPath(const char *pszPath); + const std::string get_outputPath() const; + std::string converttimetostdfoam(const boost::local_time::local_date_time& ninjaTime) ; + AsciiGrid TurbulenceGrid; private: @@ -103,7 +106,7 @@ class NinjaFoam : public ninja void ComputeDirection(); //converts direction from degrees to unit vector notation void SetInlets(); void SetBcs(); - + std::vector direction; //input.inputDirection converted to unit vector notation std::vector inlets; // e.g., north_face std::vector bcs; From bd7fad5c633540e67b1e49671fd3d939fc7cae58 Mon Sep 17 00:00:00 2001 From: Rui Date: Tue, 7 Jan 2025 19:27:55 -0500 Subject: [PATCH 10/35] always write vtk --- src/gui/mainWindow.cpp | 173 ++++++++++++++++++++--------------------- src/ninja/ninja.cpp | 78 +++++++++++-------- 2 files changed, 133 insertions(+), 118 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 1c054846..6c3ce1af 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1671,6 +1671,7 @@ std::vector mainWindow::split(const std::string &s, const std::stri int mainWindow::solve() { + bool writeCF = tree->solve->CaseFIBOX->isChecked(); CaseFile casefile; std::string getdir = tree->solve->outputDirectory().toStdString(); @@ -1697,20 +1698,18 @@ int mainWindow::solve() return 1; } - if (!tree->solve->CaseFIBOX->isChecked()) { - + if (!writeCF) { outFile.close(); - stationCSVFILE.close(); - + stationCSVFILE.close(); + casefile.setZipOpen(false); } else { - casefile.setZipOpen(true); + casefile.setZipOpen(true); } - #ifdef NINJAFOAM bool useNinjaFoam = tree->ninjafoam->ninjafoamGroupBox->isChecked(); - if (useNinjaFoam && tree->solve->CaseFIBOX->isChecked()) { + if (useNinjaFoam && writeCF) { outFile << "--momentum_flag true\n"; } #endif @@ -1720,7 +1719,7 @@ int mainWindow::solve() //dem file std::string demFile = inputFileName.toStdString(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (casefile.getDownloadedFromDEM() == true) { std::vector vec = casefile.getBoundingBox(); @@ -1743,7 +1742,7 @@ int mainWindow::solve() #ifdef NINJAFOAM std::string caseFile = existingCaseDir.toStdString(); - if (useNinjaFoam && tree->solve->CaseFIBOX->isChecked()) { + if (useNinjaFoam && writeCF) { outFile << "--existing_case_directory" << caseFile<< "\n"; } @@ -1756,19 +1755,19 @@ int mainWindow::solve() //get choice from combo if(vegIndex == 0) { vegetation = WindNinjaInputs::grass; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--vegetation grass\n"; } } else if( vegIndex == 1 ) { vegetation = WindNinjaInputs::brush; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--vegetation brush\n"; } } else if( vegIndex == 2 ) { vegetation = WindNinjaInputs::trees; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--vegetation trees\n"; } } @@ -1781,21 +1780,21 @@ int mainWindow::solve() bool customMesh = false; if( meshIndex == 0 ) { meshChoice = Mesh::coarse; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--mesh_choice coarse\n"; } } else if( meshIndex == 1 ) { meshChoice = Mesh::medium; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--mesh_choice medium\n"; } } else if( meshIndex == 2 ) { meshChoice = Mesh::fine; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--mesh_choice fine\n"; } } @@ -1806,19 +1805,19 @@ int mainWindow::solve() if( tree->surface->meshFeetRadioButton->isChecked() ) { meshUnits = lengthUnits::feet; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_mesh_resolution ft\n"; } } else { meshUnits = lengthUnits::meters; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_mesh_resolution m\n"; } } - if (customMesh && tree->solve->CaseFIBOX->isChecked()) { + if (customMesh && writeCF) { outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; } @@ -1865,7 +1864,7 @@ int mainWindow::solve() QVariant temp = tree->surface->timeZone->tzComboBox->itemData( tzIndex ); std::string timeZone = temp.toString().toStdString(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--time_zone " << timeZone <<"\n"; } @@ -1876,7 +1875,7 @@ int mainWindow::solve() //stability bool useStability = tree->stability->stabilityGroupBox->isChecked(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (useDiurnal == 0) { outFile << "--diurnal_winds false\n"; } @@ -1896,21 +1895,21 @@ int mainWindow::solve() if( tree->wind->windGroupBox->isChecked() ) { initMethod = WindNinjaInputs::domainAverageInitializationFlag; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--initialization_method domainAverageInitialization\n"; } } else if( tree->point->pointGroupBox->isChecked() ) { initMethod = WindNinjaInputs::pointInitializationFlag; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--initialization_method pointInitialization\n"; } } else if( tree->weather->weatherGroupBox->isChecked() ) { initMethod = WindNinjaInputs::wxModelInitializationFlag; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--initialization_method wxModelInitialization\n" ; } } @@ -1921,20 +1920,20 @@ int mainWindow::solve() double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits inHeightUnits; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_wind_height " << std::to_string(inHeight) << "\n" ; } if(tree->wind->metaWind->feetRadioButton->isChecked()) { inHeightUnits = lengthUnits::feet; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_input_wind_height ft\n"; } } else { inHeightUnits = lengthUnits::meters; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_input_wind_height m\n"; } } @@ -1946,28 +1945,28 @@ int mainWindow::solve() if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) { inputSpeedUnits = velocityUnits::milesPerHour; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_speed_units mph\n" ; } } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) { inputSpeedUnits = velocityUnits::metersPerSecond; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_speed_units mps\n"; } } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) { inputSpeedUnits = velocityUnits::knots; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_speed_units kts\n"; } } else { inputSpeedUnits = velocityUnits::kilometersPerHour; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_speed_units kph\n" ; } } @@ -1977,14 +1976,14 @@ int mainWindow::solve() { tempUnits = temperatureUnits::F; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--air_temp_units F\n" ; } } else if(tree->wind->windTable->airTempUnits->currentIndex() == 1){ tempUnits = temperatureUnits::C; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--air_temp_units C\n"; } } @@ -1995,7 +1994,7 @@ int mainWindow::solve() QFileInfo fi( tree->weather->model->fileInfo( mi ) ); weatherFile = fi.absoluteFilePath().toStdString(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--wx_model_type "; outFile << "--forecast_duration "<< tree->weather->hourSpinBox->value() <<"\n"; } @@ -2007,12 +2006,12 @@ int mainWindow::solve() double outHeight = tree->output->outputHeight->outputHeightDoubleSpinBox->value(); lengthUnits::eLengthUnits outHeightUnits; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--output_wind_height " <output->outputHeight->feetRadioButton->isChecked()) { - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_output_wind_height ft\n"; } @@ -2021,7 +2020,7 @@ int mainWindow::solve() else { outHeightUnits = lengthUnits::meters; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_output_wind_height m\n";} } @@ -2029,25 +2028,25 @@ int mainWindow::solve() if(tree->output->outputSpeedUnitsCombo->currentIndex() == 0) { outputSpeedUnits = velocityUnits::milesPerHour; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--output_speed_units mph\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) { outputSpeedUnits = velocityUnits::metersPerSecond; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--output_speed_units mps\n" ; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) { outputSpeedUnits = velocityUnits::kilometersPerHour; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--output_speed_units kph\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) { outputSpeedUnits = velocityUnits::knots; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--output_speed_units kts\n"; } } @@ -2061,7 +2060,7 @@ int mainWindow::solve() //google bool writeGoogle = tree->google->googleGroupBox->isChecked(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (writeGoogle) { outFile << "--write_goog_output true\n"; if( initMethod == WindNinjaInputs::wxModelInitializationFlag) { @@ -2076,7 +2075,7 @@ int mainWindow::solve() double googleRes = tree->google->googleResSpinBox->value(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_resolution " << std::to_string(googleRes)<< "\n"; } double vectorWidth = tree->google->vectorWidthDoubleSpinBox->value(); lengthUnits::eLengthUnits googleUnits; @@ -2085,12 +2084,12 @@ int mainWindow::solve() if(tree->google->googleMetersRadioButton->isChecked()) { googleUnits = lengthUnits::meters; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_goog_out_resolution m\n"; } } else { googleUnits = lengthUnits::feet; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_goog_out_resolution ft\n"; } } if(tree->google->uniformRangeRadioButton->isChecked()) @@ -2101,7 +2100,7 @@ int mainWindow::solve() std::string googleScheme; bool googVectorScaling = tree->google->applyVectorScaling->isChecked(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (googVectorScaling) { outFile << "--goog_out_vector_scaling true\n"; @@ -2120,56 +2119,56 @@ int mainWindow::solve() if (googCheckScheme=="Default") { googleScheme="default"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme ROYGB\n"; } } if (googCheckScheme=="ROPGW (Red Orange Pink Green White)") { googleScheme="ROPGW"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme ROPGW\n"; } } if (googCheckScheme=="Oranges") { googleScheme="oranges"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme oranges\n"; } } if (googCheckScheme=="Blues") { googleScheme="blues"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme blues\n"; } } if (googCheckScheme=="Pinks") { googleScheme="pinks"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme pinks\n"; } } if (googCheckScheme=="Greens") { googleScheme="greens"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme greens\n"; } } if (googCheckScheme=="Magic Beans") { googleScheme="magic_beans"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme magic_beans\n"; } } if (googCheckScheme=="Pink to Green") { googleScheme="pink_to_green"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme pink_to_green\n"; } } } @@ -2177,14 +2176,14 @@ int mainWindow::solve() { googleScheme="default"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--goog_out_color_scheme ROYGB\n"; } } //ascii raster fb files bool writeFb = tree->fb->fbGroupBox->isChecked(); double fbRes = tree->fb->fbResSpinBox->value(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (writeFb) { outFile << "--write_ascii_output true\n"; @@ -2203,12 +2202,12 @@ int mainWindow::solve() lengthUnits::eLengthUnits fbUnits; if(tree->fb->fbMetersRadioButton->isChecked()) { fbUnits = lengthUnits::meters; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_ascii_out_resolution m\n"; } } else { fbUnits = lengthUnits::feet; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_ascii_out_resolution ft\n"; } } //write atmosphere file? @@ -2246,7 +2245,7 @@ int mainWindow::solve() double shapeRes = tree->shape->shapeResSpinBox->value(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (writeAtm) { outFile << "--write_farsite_atm true\n"; } @@ -2273,12 +2272,12 @@ int mainWindow::solve() lengthUnits::eLengthUnits shapeUnits; if(tree->shape->shapeMetersRadioButton->isChecked()) { shapeUnits = lengthUnits::meters; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_shape_out_resolution m\n"; } } else{ shapeUnits = lengthUnits::feet; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_shape_out_resolution ft\n"; } } //pdf @@ -2289,19 +2288,19 @@ int mainWindow::solve() lengthUnits::eLengthUnits pdfUnits; if(tree->pdf->pdfMetersRadioButton->isChecked()) { - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_pdf_out_resolution m\n"; } pdfUnits = lengthUnits::meters; } else { - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--units_pdf_out_resolution ft\n"; } pdfUnits = lengthUnits::feet; } int pdfBase = tree->pdf->backgroundComboBox->currentIndex(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (writePdf) { outFile << "--write_pdf_output true\n"; } @@ -2325,7 +2324,7 @@ int mainWindow::solve() { pdfHeight = 11.0; pdfWidth = 8.5; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--pdf_size letter\n" ;} } // Legal @@ -2334,7 +2333,7 @@ int mainWindow::solve() pdfHeight = 14.0; pdfWidth = 8.5; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--pdf_size legal\n";} } // Tabloid @@ -2343,7 +2342,7 @@ int mainWindow::solve() pdfHeight = 17.0; pdfWidth = 11.0; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--pdf_size tabloid\n";} } if( tree->pdf->landscapeRadioButton->isChecked() ) @@ -2360,7 +2359,7 @@ int mainWindow::solve() //number of processors int nThreads = tree->solve->numProcSpinBox->value(); -if (tree->solve->CaseFIBOX->isChecked()) { +if (writeCF) { outFile << "--num_threads " <solve->CaseFIBOX->isChecked()) { bool writeStationKML = tree->point->writeStationKmlButton->isChecked(); //Write a kml file bool writeStationCSV = tree->point->writeStationFileButton->isChecked(); //hidden for now std::vector fullFileListPoint = tree->point->fullFileList; - if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true && tree->solve->CaseFIBOX->isChecked()) { + if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true && writeCF) { // for each file append it to csv // if any point file is under a wx station folder just copy the entire folder over - otherwise no @@ -2429,7 +2428,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { } - else if (tree->solve->CaseFIBOX->isChecked()) { + else if (writeCF) { outFile << "--fetch_station false\n"; if (useTimeList) { @@ -2481,7 +2480,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { } } - if ((tree->solve->CaseFIBOX->isChecked()) ) { + if ((writeCF) ) { for (std::string & pfile : fullFileListPoint) { std::vector tokens = split(pfile, "/"); @@ -2567,7 +2566,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { } try{ //Try to run windninja - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--match_points true\n";} army->makeStationArmy(timeList,timeZone, pointFile, demFile, true,false); } @@ -2626,7 +2625,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { try{ //try running with timelist - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--match_points true\n";} army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); //setting pointFileList[0] is just for header checks etc } @@ -2662,7 +2661,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { pointInitialization::storeFileNames(pointFileList); try{ //try making the army with current data - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--match_points true\n";} army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); } @@ -2740,7 +2739,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { std::string metaPath = std::string(CPLFormFilename(pathDem.c_str(),baseMeta.c_str(),".csv")); CPLDebug("STATION_FETCH","Saving Metadata to: %s",metaPath.c_str()); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--fetch_metadata true\n"; outFile << "--metadata_filename" << metaPath<< "\n"; } pointInitialization::fetchMetaData(metaPath,demFile,true); @@ -2780,7 +2779,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { if ( times.size() > 0 ) { - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); @@ -2850,7 +2849,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { //get times for casefile if no times are clicked by user - if (times.size() == 0 && tree->solve->CaseFIBOX->isChecked()) { + if (times.size() == 0 && writeCF) { std::vector wxtimesfromcasefile = casefile.getWXTIME(); @@ -2892,7 +2891,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { runProgress = new int[nRuns]; //I don't think this is needed anymore std::string outputDir = tree->solve->outputDirectory().toStdString(); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--output_path " << outputDir<< "\n" ; } if( outputDir == "" ) { @@ -2935,14 +2934,14 @@ if (tree->solve->CaseFIBOX->isChecked()) { else if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { //get speed - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_speed " <wind->windTable->speed[i]->value()) << "\n"; } army->setInputSpeed( i, tree->wind->windTable->speed[i]->value(), inputSpeedUnits); //get direction - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--input_direction " <wind->windTable->dir[i]->value()) <<"\n"; } army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); @@ -2968,7 +2967,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; domainRUNS << "--month " <wind->windTable->date[i]->date().month() << "\n"; @@ -2989,7 +2988,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { tree->wind->windTable->airTemp[i]->value(), tempUnits ); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; @@ -3019,7 +3018,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { domainRUNS << "--year " <wind->windTable->date[i]->date().year() <<"\n"; @@ -3043,7 +3042,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { tree->wind->windTable->airTemp[i]->value(), tempUnits ); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value() << "\n"; domainRUNS << "--uni_air_temp " <wind->windTable->airTemp[i]->value() << "\n"; @@ -3070,7 +3069,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { #ifdef NINJAFOAM if(useNinjaFoam){ - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if(ninjafoamMeshChoice == WindNinjaInputs::coarse){ outFile << "--mesh_count 25000\n"; } @@ -3083,7 +3082,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { } army->setMeshCount( i, ninjafoamMeshChoice ); - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile << "--number_of_iterations 300\n";} army->setNumberOfIterations( i, 300); } @@ -3141,7 +3140,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { std::string domainaveragepath = "DomainAverage/run " + std::to_string(i) + ".cfg"; std::string domainaveragedeletion = "domainrun" + std::to_string(i) + ".cfg"; - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { casefile.addFileToZip(zipFilePath, getdir, domainaveragepath, domaininputpath ); } @@ -3152,7 +3151,7 @@ if (tree->solve->CaseFIBOX->isChecked()) { //set Casefile Directory and Input - if (tree->solve->CaseFIBOX->isChecked()) { + if (writeCF) { outFile.close(); casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index aec91ff8..a0018dd5 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2816,10 +2816,56 @@ std::string ninja::converttimetostd(const boost::local_time::local_date_time& ni void ninja::writeOutputFiles() { set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); + + + // write to casefile regardless of if VTK is checked + bool VTKforcasefile = false; + CaseFile casefile; + if (casefile.getZipOpen()) { + VTKforcasefile = true; + bool vtk_out_as_utm = false; + if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) + { + vtk_out_as_utm = CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"); + } + // can pick between "ascii" and "binary" format for the vtk write format + std::string vtkWriteFormat = "binary";//"binary";//"ascii"; + volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); + std::string directoryPath = get_outputPath(); + std::string normfile = casefile.parse("file", input.volVTKFile); + std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); + std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); + + std::string timestr = ""; + std:: string getlocaltime = casefile.getTime(); + + //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; + if (input.ninjaTime.is_not_a_date_time()) { + timestr = getlocaltime; + } + else { + + timestr = converttimetostd(input.ninjaTime); + + } + + std::string getfileName = casefile.parse("file", input.dem.fileName); + + std::string zipFilePath = casefile.getzip(); + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); + + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + casefile.deleteFileFromPath(directoryPath , normfile); + casefile.deleteFileFromPath(directoryPath , surfFile); + + } //Write volume data to VTK format (always in m/s?) - if(input.volVTKOutFlag) + + if(input.volVTKOutFlag && !VTKforcasefile) { + std::cout << "test" << std::endl; try{ bool vtk_out_as_utm = false; if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) @@ -2829,37 +2875,7 @@ void ninja::writeOutputFiles() // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "binary";//"binary";//"ascii"; volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - CaseFile casefile; - - if (casefile.getZipOpen()) { - std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", input.volVTKFile); - std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); - std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); - - std::string timestr = ""; - std:: string getlocaltime = casefile.getTime(); - - //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; - if (input.ninjaTime.is_not_a_date_time()) { - timestr = getlocaltime; - } - else { - - timestr = converttimetostd(input.ninjaTime); - - } - - std::string getfileName = casefile.parse("file", input.dem.fileName); - std::string zipFilePath = casefile.getzip(); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); - casefile.deleteFileFromPath(directoryPath , normfile); - casefile.deleteFileFromPath(directoryPath , surfFile); - } } catch (exception& e) { From 0f68a691dd80a20e75e9a093361c3a10b8f6e583 Mon Sep 17 00:00:00 2001 From: Rui Date: Thu, 6 Mar 2025 08:36:26 -0500 Subject: [PATCH 11/35] naming convention fix --- src/gui/mainWindow.cpp | 95 +++++++++++++++++++++-------------------- src/gui/mainWindow.h | 1 + src/ninja/casefile.cpp | 15 +++++++ src/ninja/casefile.h | 1 + src/ninja/ninja.cpp | 41 +++++++++++++++--- src/ninja/ninja.h | 3 ++ src/ninja/ninjafoam.cpp | 44 ++++++++++++++++--- src/ninja/ninjafoam.h | 3 ++ 8 files changed, 144 insertions(+), 59 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 6c3ce1af..a98428cd 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1675,6 +1675,7 @@ int mainWindow::solve() CaseFile casefile; std::string getdir = tree->solve->outputDirectory().toStdString(); + std::string inputpath = getdir + "/config.cfg"; std::string stationCSVFILEPATH = getdir + "/selectedstations.csv"; std::string getfileName = casefile.parse("file", inputFileName.toStdString()); @@ -1701,7 +1702,11 @@ int mainWindow::solve() if (!writeCF) { outFile.close(); stationCSVFILE.close(); + casefile.setZipOpen(false); + casefile.deleteFileFromPath(getdir, "config.cfg"); + + casefile.deleteFileFromPath(getdir, "selectedstations.csv"); } else { casefile.setZipOpen(true); @@ -2899,13 +2904,44 @@ if (writeCF) { throw( "no output directory specified in solve page" ); } - //fill in the values for(int i = 0;i < army->getSize(); i++) { + CPLSetConfigOption("CPL_DEBUG", "ON"); std::string domaininputpath = getdir + "/domainrun" + std::to_string(i) + ".cfg"; + + std::ofstream domainRUNS(domaininputpath); + // add runs to files + if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) + { + if (writeCF) { + + domainRUNS << "--input_speed " << tree->wind->windTable->speed[i]->value() << "\n"; + + domainRUNS << "--input_direction " << tree->wind->windTable->dir[i]->value() << "\n"; + + domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; + + + domainRUNS << "--month " <wind->windTable->date[i]->date().month() << "\n"; + + domainRUNS << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; + + domainRUNS << "--hour " <wind->windTable->time[i]->time().hour() << "\n"; + + domainRUNS << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; + + domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; + domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; + + domainRUNS << "--cloud_cover_units percent" << "\n" ; + } + + } + + army->setDEM( i, demFile ); #ifdef NINJAFOAM if(caseFile != ""){ @@ -2943,7 +2979,7 @@ if (writeCF) { if (writeCF) { outFile << "--input_direction " <wind->windTable->dir[i]->value()) <<"\n"; } - + army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); army->setInputWindHeight ( i, inHeight, inHeightUnits ); @@ -2961,23 +2997,17 @@ if (writeCF) { army->setOutputPath( i, outputDir.c_str() ); //diurnal, if needed - army->setDiurnalWinds( i, useDiurnal ); + army->setDiurnalWinds( i, useDiurnal ); + + + + + if( useDiurnal == true ) { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - if (writeCF) { - domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; - - domainRUNS << "--month " <wind->windTable->date[i]->date().month() << "\n"; - - domainRUNS << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; - - domainRUNS << "--hour " <wind->windTable->time[i]->time().hour() << "\n"; - - domainRUNS << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; - } army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), @@ -2988,12 +3018,6 @@ if (writeCF) { tree->wind->windTable->airTemp[i]->value(), tempUnits ); - if (writeCF) { - domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; - domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; - - domainRUNS << "--cloud_cover_units percent" << "\n" ; - } army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -3018,20 +3042,7 @@ if (writeCF) { { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - if (writeCF) { - - domainRUNS << "--year " <wind->windTable->date[i]->date().year() <<"\n"; - - domainRUNS << "--month " <wind->windTable->date[i]->date().month() <<"\n"; - - domainRUNS << "--day " <wind->windTable->date[i]->date().day() <<"\n"; - - domainRUNS << "--hour " << - tree->wind->windTable->time[i]->time().hour()<< "\n"; - - domainRUNS << "--minute "<< tree->wind->windTable->time[i]->time().minute()<<"\n"; - } army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), @@ -3042,12 +3053,7 @@ if (writeCF) { tree->wind->windTable->airTemp[i]->value(), tempUnits ); - if (writeCF) { - domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value() << "\n"; - - domainRUNS << "--uni_air_temp " <wind->windTable->airTemp[i]->value() << "\n"; - domainRUNS << "--cloud_cover_units percent\n"; - } + army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -3132,21 +3138,20 @@ if (writeCF) { //army.setOutputFilenames(); army->setNinjaComNumRuns( i, nRuns ); - - //add different input to config domainRUNS.close(); std::string domainaveragepath = "DomainAverage/run " + std::to_string(i) + ".cfg"; std::string domainaveragedeletion = "domainrun" + std::to_string(i) + ".cfg"; - + std::cout << domainaveragepath << std::endl; + std::cout << domainaveragedeletion << std::endl; if (writeCF) { if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { casefile.addFileToZip(zipFilePath, getdir, domainaveragepath, domaininputpath ); } - - casefile.deleteFileFromPath(getdir, domainaveragedeletion ); } + casefile.deleteFileFromPath(getdir, domainaveragedeletion ); + } //set Casefile Directory and Input @@ -3155,9 +3160,7 @@ if (writeCF) { outFile.close(); casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); - casefile.deleteFileFromPath(getdir, "selectedstations.csv"); } diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index bc3a9b5d..f398bd59 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -67,6 +67,7 @@ #include "ninjaUnits.h" #include "ninjaArmy.h" #include "ninja_conv.h" +#include "cpl_conv.h" // For CPLSetConfigOption #include "setconfigdialog.h" diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 8221765e..2fb6a948 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -175,6 +175,20 @@ std::string CaseFile::getTime() { return oss.str(); } +void CaseFile::rename(std::string newname) { + + std::string directory = getdir(); + std::string oldFilePath = zipfilename; + std::string newFilePath = newname ; + + if (VSIRename(oldFilePath.c_str(), newFilePath.c_str()) == 0) { + CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", oldFilePath.c_str(), newFilePath.c_str()); + zipfilename = newname; + } else { + CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", oldFilePath.c_str(), newFilePath.c_str()); + } +} + void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filename) { @@ -210,6 +224,7 @@ std::string CaseFile::getzip() { return zipfilename; } + void CaseFile::setzip(std::string zip) { zipfilename = zip; } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index c20f2188..4ef4d345 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -71,6 +71,7 @@ class CaseFile { bool lookfordate(const std::string& date) ; std::string getTime(); + void rename(std::string newname); std::string getdir() ; void setdir(std::string dir); diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index a0018dd5..3693fa3f 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -34,6 +34,7 @@ extern boost::local_time::tz_database globalTimeZoneDB; /**Ninja constructor * This is the default ninja constructor. */ + std::string casefilename = ""; ninja::ninja() { cancel = false; @@ -82,6 +83,8 @@ ninja::ninja() input.inputsRunNumber = 0; input.inputsComType = ninjaComClass::ninjaDefaultCom; input.Com = new ninjaDefaultComHandler(); + casefilename = ""; + } @@ -153,7 +156,7 @@ ninja::ninja(const ninja &rhs) endSolve=0.0; startWriteOut=0.0; endWriteOut=0.0; - + casefilename = ""; //Pointers to dynamically allocated memory DIAG=NULL; PHI=NULL; @@ -2817,11 +2820,12 @@ void ninja::writeOutputFiles() { set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); - + // write to casefile regardless of if VTK is checked bool VTKforcasefile = false; CaseFile casefile; if (casefile.getZipOpen()) { + casefile.rename(casefilename + ".ninja"); VTKforcasefile = true; bool vtk_out_as_utm = false; if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) @@ -2865,7 +2869,6 @@ void ninja::writeOutputFiles() if(input.volVTKOutFlag && !VTKforcasefile) { - std::cout << "test" << std::endl; try{ bool vtk_out_as_utm = false; if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) @@ -4868,6 +4871,7 @@ void ninja::set_outputFilenames(double& meshResolution, lengthUnits::eLengthUnits meshResolutionUnits) { //Set output file resolutions now + if( input.kmzResolution <= 0.0 ) //if negative, use computational mesh resolution input.kmzResolution = meshResolution; if( input.shpResolution <= 0.0 ) //if negative, use computational mesh resolution @@ -4888,7 +4892,7 @@ void ninja::set_outputFilenames(double& meshResolution, timeOutputFacet = new boost::local_time::local_time_facet(); //NOTE: WEIRD ISSUE WITH THE ABOVE 2 LINES OF CODE! DO NOT CALL DELETE ON THIS BECAUSE THE LOCALE OBJECT BELOW DOES. // THIS IS A "PROBLEM" IN THE STANDARD LIBRARY. SEE THESE WEB SITES FOR MORE INFO: - // https://collab.firelab.org/software/projects/windninja/wiki/KnownIssues + // https://collab.firelab.org/software/projects/windninja/wiki/KnonIssues // http://rhubbarb.wordpress.com/2009/10/17/boost-datetime-locales-and-facets/#comment-203 std::ostringstream timestream; @@ -4965,11 +4969,16 @@ void ninja::set_outputFilenames(double& meshResolution, pdf_mesh_units = lengthUnits::getString( input.pdfUnits ); ostringstream os, os_kmz, os_shp, os_ascii, os_pdf; + std::ostringstream os_case; + os_case << rootFile << "_" << timeAppend; + if( input.initializationMethod == WindNinjaInputs::domainAverageInitializationFlag || input.initializationMethod == WindNinjaInputs::foamDomainAverageInitializationFlag ) { double tempSpeed = input.inputSpeed; velocityUnits::fromBaseUnits(tempSpeed, input.inputSpeedUnits); + os_case << "_DA"; + os << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_kmz << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_shp << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); @@ -4978,14 +4987,18 @@ void ninja::set_outputFilenames(double& meshResolution, } else if( input.initializationMethod == WindNinjaInputs::pointInitializationFlag ) { + os_case << "_PointInit"; + os << "_point"; os_kmz << "_point"; os_shp << "_point"; os_ascii << "_point"; os_pdf << "_point"; } - - + else if( input.initializationMethod == WindNinjaInputs::wxModelInitializationFlag ) + { + os_case << "_WxModel"; + } double meshResolutionTemp = meshResolution; double kmzResolutionTemp = input.kmzResolution; double shpResolutionTemp = input.shpResolution; @@ -5004,8 +5017,19 @@ void ninja::set_outputFilenames(double& meshResolution, os_ascii << "_" << timeAppend << (long) (velResolutionTemp+0.5) << ascii_mesh_units; os_pdf << "_" << timeAppend << (long) (pdfResolutionTemp+0.5) << pdf_mesh_units; + os_case << "_munit" << mesh_units; + + os_case << "_kmz" << (long)(kmzResolutionTemp + 0.5) << kmz_mesh_units + << "_shp" << (long)(shpResolutionTemp + 0.5) << shp_mesh_units + << "_ascii" << (long)(velResolutionTemp + 0.5) << ascii_mesh_units + << "_pdf" << (long)(pdfResolutionTemp + 0.5) << pdf_mesh_units; + + + if( input.stabilityFlag == true && input.alphaStability != -1 ) { + os_case << "_alpha_" << input.alphaStability; + os << "_alpha_" << input.alphaStability; os_kmz << "_alpha_" << input.alphaStability; os_shp << "_alpha_" << input.alphaStability; @@ -5014,6 +5038,8 @@ void ninja::set_outputFilenames(double& meshResolution, } else if( input.stabilityFlag == true && input.alphaStability == -1 ) { + os_case << "_non_neutral_stability"; + os << "_non_neutral_stability"; os_kmz << "_non_neutral_stability"; os_shp << "_non_neutral_stability"; @@ -5027,6 +5053,9 @@ void ninja::set_outputFilenames(double& meshResolution, ascii_fileAppend = os_ascii.str(); pdf_fileAppend = os_pdf.str(); + casefilename = os_case.str(); + + input.kmlFile = rootFile + kmz_fileAppend + ".kml"; input.kmzFile = rootFile + kmz_fileAppend + ".kmz"; diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index c218b622..c9af43c3 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -118,6 +118,9 @@ //#define NINJA_DEBUG //#define NINJA_DEBUG_VERBOSE +extern std::string casefilename; + + class ninja { diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 32e540a0..cceb655d 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -30,11 +30,12 @@ #include "ninjafoam.h" const char* NinjaFoam::pszFoamPath = NULL; + std::string casefilenamefoam = ""; NinjaFoam::NinjaFoam() : ninja() { foamVersion = ""; - + casefilenamefoam = ""; pszVrtMem = NULL; pszGridFilename = NULL; pszTurbulenceGridFilename = NULL; @@ -2165,6 +2166,8 @@ void NinjaFoam::SetOutputFilenames() shp_fileAppend, ascii_fileAppend, mesh_units, kmz_mesh_units, \ shp_mesh_units, ascii_mesh_units, pdf_fileAppend, pdf_mesh_units; + + boost::local_time::local_time_facet* timeOutputFacet; timeOutputFacet = new boost::local_time::local_time_facet(); //NOTE: WEIRD ISSUE WITH THE ABOVE 2 LINES OF CODE! DO NOT CALL DELETE ON THIS BECAUSE THE LOCALE OBJECT BELOW DOES. @@ -2205,6 +2208,7 @@ void NinjaFoam::SetOutputFilenames() input.outputPath = pathName; timeAppend = timestream.str(); + ostringstream wxModelTimestream; boost::local_time::local_time_facet* wxModelOutputFacet; @@ -2223,6 +2227,8 @@ void NinjaFoam::SetOutputFilenames() pdf_mesh_units = lengthUnits::getString( input.pdfUnits ); ostringstream os, os_kmz, os_shp, os_ascii, os_pdf; + std::ostringstream os_case; + os_case << rootFile << "_" << timeAppend << "_FOAM"; if( input.initializationMethod == WindNinjaInputs::domainAverageInitializationFlag ){ double tempSpeed = input.inputSpeed; @@ -2232,8 +2238,13 @@ void NinjaFoam::SetOutputFilenames() os_shp << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_ascii << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_pdf << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); + os_case << "_DA"; + } + if( input.initializationMethod == WindNinjaInputs::wxModelInitializationFlag){ + os_case << "_WxModel"; } + double meshResolutionTemp = input.dem.get_cellSize(); double kmzResolutionTemp = input.kmzResolution; double shpResolutionTemp = input.shpResolution; @@ -2253,12 +2264,26 @@ void NinjaFoam::SetOutputFilenames() os_shp << "_" << timeAppend << (long) (shpResolutionTemp+0.5) << shp_mesh_units; os_ascii << "_" << timeAppend << (long) (velResolutionTemp+0.5) << ascii_mesh_units; os_pdf << "_" << timeAppend << (long) (pdfResolutionTemp+0.5) << pdf_mesh_units; + + fileAppend = os.str(); kmz_fileAppend = os_kmz.str(); shp_fileAppend = os_shp.str(); ascii_fileAppend = os_ascii.str(); pdf_fileAppend = os_pdf.str(); + + os_case << "_munit" << mesh_units; + + os_case << "_kmz" << (long)(kmzResolutionTemp + 0.5) << kmz_mesh_units + << "_shp" << (long)(shpResolutionTemp + 0.5) << shp_mesh_units + << "_ascii" << (long)(velResolutionTemp + 0.5) << ascii_mesh_units + << "_pdf" << (long)(pdfResolutionTemp + 0.5) << pdf_mesh_units; + + + + // Assign final casefilenam + casefilenamefoam = os_case.str(); input.kmlFile = rootFile + kmz_fileAppend + ".kml"; input.kmzFile = rootFile + kmz_fileAppend + ".kmz"; @@ -2645,6 +2670,12 @@ void NinjaFoam::WriteOutputFiles() CPLDebug("NINJAFOAM", "writing mass mesh vtk output for foam simulation."); writeMassMeshVtkOutput(); } + CaseFile casefile; + // write mass mesh if casefile is turned on - casefile always needs a vtk + if (writeMassMeshVtk != true && casefile.getZipOpen()) { + CPLDebug("NINJAFOAM", "TRY to write mass mesh vtk output for foam simulation."); + writeMassMeshVtkOutput(); + } }catch (exception& e) { input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during NINJAFOAM mass mesh vtk file writing: %s", e.what()); @@ -2680,7 +2711,6 @@ void NinjaFoam::writeMassMeshVtkOutput() massMesh.buildStandardMesh(input); - // no longer need to resize any of the ascii grids, even L and bl_height, as they are already at the mass mesh resolution // after the dem is resampled to the mesh resolution they are set using the dem resolution, // and the mesh resolution now is expected to always match the mass solver mesh resolution @@ -2711,16 +2741,16 @@ void NinjaFoam::writeMassMeshVtkOutput() } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; - std::cerr << "hello" << std::endl; volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); CaseFile casefile; if (casefile.getZipOpen()) { + casefile.rename(casefilenamefoam); std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", input.volVTKFile); - std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); - std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); + std::string normfile = casefile.parse("file", massMeshVtkFilename); + std::string directoryofVTK = casefile.parse("directory", massMeshVtkFilename); + std::string surfFile = casefile.parse("file", massMeshVtkFilename).substr(0, casefile.parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile.parse("file", massMeshVtkFilename).substr(casefile.parse("file", massMeshVtkFilename).length() - 4, casefile.parse("file", massMeshVtkFilename).length()); std::string timestr = ""; std:: string getlocaltime = casefile.getTime(); @@ -2739,7 +2769,7 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string zipFilePath = casefile.getzip(); - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, massMeshVtkFilename); casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); casefile.deleteFileFromPath(directoryPath , normfile); diff --git a/src/ninja/ninjafoam.h b/src/ninja/ninjafoam.h index 86325515..ab0d990a 100644 --- a/src/ninja/ninjafoam.h +++ b/src/ninja/ninjafoam.h @@ -59,6 +59,9 @@ " " \ "" + +extern std::string casefilenamefoam; + /** * \brief Main interface to OpenFOAM solver runs. * From 03cc35f9fa9231055fe60b9fdf278091d77f5638 Mon Sep 17 00:00:00 2001 From: latwood Date: Tue, 11 Mar 2025 19:35:41 -0600 Subject: [PATCH 12/35] segfault fix for case file cli of domain average runs --- src/ninja/casefile.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 2fb6a948..af2e542a 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -71,6 +71,11 @@ std::string CaseFile::parse(const std::string& type, const std::string& path) { if (strcmp(type.c_str(), "file") == 0) { return path.substr(found + 1); // Extract substring after the last '/' } + } else + { + //std::cout << "couldn't parse" << std::endl; + //return ""; + return path; } } From bdc0c893cb358b173b38ee977dec4bf6cf1c0114 Mon Sep 17 00:00:00 2001 From: latwood Date: Wed, 12 Mar 2025 18:12:57 -0600 Subject: [PATCH 13/35] fix case file vtk output in ninjafoam, wasn't getting properly generated. for issue #7 --- src/ninja/ninjafoam.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index cceb655d..d4f71812 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2666,14 +2666,10 @@ void NinjaFoam::WriteOutputFiles() try{ - if ( writeMassMeshVtk == true ) { - CPLDebug("NINJAFOAM", "writing mass mesh vtk output for foam simulation."); - writeMassMeshVtkOutput(); - } CaseFile casefile; // write mass mesh if casefile is turned on - casefile always needs a vtk - if (writeMassMeshVtk != true && casefile.getZipOpen()) { - CPLDebug("NINJAFOAM", "TRY to write mass mesh vtk output for foam simulation."); + if (writeMassMeshVtk == true || casefile.getZipOpen()) { + CPLDebug("NINJAFOAM", "writing mass mesh vtk output for foam simulation."); writeMassMeshVtkOutput(); } }catch (exception& e) @@ -3825,7 +3821,9 @@ void NinjaFoam::SetMeshResolutionAndResampleDem() } - if ( writeMassMeshVtk == true ) { + CaseFile casefile; + // write mass mesh if casefile is turned on - casefile always needs a vtk + if (writeMassMeshVtk == true || casefile.getZipOpen()) { // need to setup mesh sizing BEFORE the dem gets resampled, but AFTER the mesh resolution gets set massMesh.set_numVertLayers(20); // done in cli.cpp calling ninja_army calling ninja calling this function, with windsim.setNumVertLayers( i_, 20); where i_ is ninjaIdx CPLDebug("NINJAFOAM", "mass mesh vtk output set by mesh resolution, %f %s", meshResolution, lengthUnits::getString(meshResolutionUnits).c_str()); From 7a698dbcd6565f64763d341bad1863fb5b886682 Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 13 Mar 2025 12:30:27 -0600 Subject: [PATCH 14/35] fix case file naming method to match conventional output filenaming, also a hint of formatting style fix for case file name storage, for issue #7 --- src/ninja/ninja.cpp | 49 +++++++++++++---------------------------- src/ninja/ninja.h | 5 ++--- src/ninja/ninjafoam.cpp | 39 +++++++++----------------------- 3 files changed, 28 insertions(+), 65 deletions(-) diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 3693fa3f..6ca6a764 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -34,7 +34,6 @@ extern boost::local_time::tz_database globalTimeZoneDB; /**Ninja constructor * This is the default ninja constructor. */ - std::string casefilename = ""; ninja::ninja() { cancel = false; @@ -83,9 +82,8 @@ ninja::ninja() input.inputsRunNumber = 0; input.inputsComType = ninjaComClass::ninjaDefaultCom; input.Com = new ninjaDefaultComHandler(); - casefilename = ""; - + casefilename = ""; } /**Ninja destructor @@ -2825,7 +2823,7 @@ void ninja::writeOutputFiles() bool VTKforcasefile = false; CaseFile casefile; if (casefile.getZipOpen()) { - casefile.rename(casefilename + ".ninja"); + casefile.rename(casefilename); VTKforcasefile = true; bool vtk_out_as_utm = false; if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) @@ -4871,7 +4869,6 @@ void ninja::set_outputFilenames(double& meshResolution, lengthUnits::eLengthUnits meshResolutionUnits) { //Set output file resolutions now - if( input.kmzResolution <= 0.0 ) //if negative, use computational mesh resolution input.kmzResolution = meshResolution; if( input.shpResolution <= 0.0 ) //if negative, use computational mesh resolution @@ -4884,7 +4881,7 @@ void ninja::set_outputFilenames(double& meshResolution, input.pdfResolution = meshResolution; //Do file naming string stuff for all output files - std::string rootFile, rootName, fileAppend, timeAppend, wxModelTimeAppend, kmz_fileAppend, \ + std::string rootFile, rootName, fileAppend, timeAppend, wxModelTimeAppend, case_fileAppend, kmz_fileAppend, \ shp_fileAppend, ascii_fileAppend, volVTK_fileAppend, mesh_units, kmz_mesh_units, \ shp_mesh_units, ascii_mesh_units, pdf_fileAppend, pdf_mesh_units; @@ -4892,7 +4889,7 @@ void ninja::set_outputFilenames(double& meshResolution, timeOutputFacet = new boost::local_time::local_time_facet(); //NOTE: WEIRD ISSUE WITH THE ABOVE 2 LINES OF CODE! DO NOT CALL DELETE ON THIS BECAUSE THE LOCALE OBJECT BELOW DOES. // THIS IS A "PROBLEM" IN THE STANDARD LIBRARY. SEE THESE WEB SITES FOR MORE INFO: - // https://collab.firelab.org/software/projects/windninja/wiki/KnonIssues + // https://collab.firelab.org/software/projects/windninja/wiki/KnownIssues // http://rhubbarb.wordpress.com/2009/10/17/boost-datetime-locales-and-facets/#comment-203 std::ostringstream timestream; @@ -4968,18 +4965,15 @@ void ninja::set_outputFilenames(double& meshResolution, ascii_mesh_units = lengthUnits::getString( input.velOutputFileDistanceUnits ); pdf_mesh_units = lengthUnits::getString( input.pdfUnits ); - ostringstream os, os_kmz, os_shp, os_ascii, os_pdf; - std::ostringstream os_case; - os_case << rootFile << "_" << timeAppend; + ostringstream os, os_case, os_kmz, os_shp, os_ascii, os_pdf; if( input.initializationMethod == WindNinjaInputs::domainAverageInitializationFlag || input.initializationMethod == WindNinjaInputs::foamDomainAverageInitializationFlag ) { double tempSpeed = input.inputSpeed; velocityUnits::fromBaseUnits(tempSpeed, input.inputSpeedUnits); - os_case << "_DA"; - os << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); + os_case << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_kmz << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_shp << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_ascii << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); @@ -4987,18 +4981,15 @@ void ninja::set_outputFilenames(double& meshResolution, } else if( input.initializationMethod == WindNinjaInputs::pointInitializationFlag ) { - os_case << "_PointInit"; - os << "_point"; + os_case << "_point"; os_kmz << "_point"; os_shp << "_point"; os_ascii << "_point"; os_pdf << "_point"; } - else if( input.initializationMethod == WindNinjaInputs::wxModelInitializationFlag ) - { - os_case << "_WxModel"; - } + + double meshResolutionTemp = meshResolution; double kmzResolutionTemp = input.kmzResolution; double shpResolutionTemp = input.shpResolution; @@ -5012,25 +5003,16 @@ void ninja::set_outputFilenames(double& meshResolution, lengthUnits::fromBaseUnits(pdfResolutionTemp, input.pdfUnits); os << "_" << timeAppend << (long) (meshResolutionTemp+0.5) << mesh_units; + os_case << "_" << timeAppend << (long) (meshResolutionTemp+0.5) << mesh_units; os_kmz << "_" << timeAppend << (long) (kmzResolutionTemp+0.5) << kmz_mesh_units; os_shp << "_" << timeAppend << (long) (shpResolutionTemp+0.5) << shp_mesh_units; os_ascii << "_" << timeAppend << (long) (velResolutionTemp+0.5) << ascii_mesh_units; os_pdf << "_" << timeAppend << (long) (pdfResolutionTemp+0.5) << pdf_mesh_units; - os_case << "_munit" << mesh_units; - - os_case << "_kmz" << (long)(kmzResolutionTemp + 0.5) << kmz_mesh_units - << "_shp" << (long)(shpResolutionTemp + 0.5) << shp_mesh_units - << "_ascii" << (long)(velResolutionTemp + 0.5) << ascii_mesh_units - << "_pdf" << (long)(pdfResolutionTemp + 0.5) << pdf_mesh_units; - - - if( input.stabilityFlag == true && input.alphaStability != -1 ) { - os_case << "_alpha_" << input.alphaStability; - os << "_alpha_" << input.alphaStability; + os_case << "_alpha_" << input.alphaStability; os_kmz << "_alpha_" << input.alphaStability; os_shp << "_alpha_" << input.alphaStability; os_ascii << "_alpha_" << input.alphaStability; @@ -5038,9 +5020,8 @@ void ninja::set_outputFilenames(double& meshResolution, } else if( input.stabilityFlag == true && input.alphaStability == -1 ) { - os_case << "_non_neutral_stability"; - os << "_non_neutral_stability"; + os_case << "_non_neutral_stability"; os_kmz << "_non_neutral_stability"; os_shp << "_non_neutral_stability"; os_ascii << "_non_neutral_stability"; @@ -5048,14 +5029,14 @@ void ninja::set_outputFilenames(double& meshResolution, } fileAppend = os.str(); + case_fileAppend = os_case.str(); kmz_fileAppend = os_kmz.str(); shp_fileAppend = os_shp.str(); ascii_fileAppend = os_ascii.str(); pdf_fileAppend = os_pdf.str(); - casefilename = os_case.str(); - - + + casefilename = rootFile + case_fileAppend + ".ninja"; input.kmlFile = rootFile + kmz_fileAppend + ".kml"; input.kmzFile = rootFile + kmz_fileAppend + ".kmz"; diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index c9af43c3..fd7dd30e 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -118,9 +118,6 @@ //#define NINJA_DEBUG //#define NINJA_DEBUG_VERBOSE -extern std::string casefilename; - - class ninja { @@ -136,6 +133,8 @@ class ninja bool cancel; //if set to "false" during a simulation (ie when "simulate_wind()" is running), the simulation will attempt to end Mesh mesh; + std::string casefilename; + //output grids to access the final wind grids (typically used by other programs running the windninja API such as WFDSS, FlamMap, etc. AsciiGridAngleGrid; AsciiGridVelocityGrid; diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index d4f71812..242f2e7d 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -30,12 +30,11 @@ #include "ninjafoam.h" const char* NinjaFoam::pszFoamPath = NULL; - std::string casefilenamefoam = ""; NinjaFoam::NinjaFoam() : ninja() { foamVersion = ""; - casefilenamefoam = ""; + pszVrtMem = NULL; pszGridFilename = NULL; pszTurbulenceGridFilename = NULL; @@ -73,7 +72,9 @@ NinjaFoam::NinjaFoam() : ninja() endOutputSampling = 0.0; startStlConversion = 0.0; endStlConversion = 0.0; - + + casefilename = ""; + writeMassMeshVtk = false; } @@ -2162,12 +2163,10 @@ void NinjaFoam::SetOutputResolution() void NinjaFoam::SetOutputFilenames() { //Do file naming string stuff for all output files - std::string rootFile, rootName, timeAppend, wxModelTimeAppend, fileAppend, kmz_fileAppend, \ + std::string rootFile, rootName, timeAppend, wxModelTimeAppend, fileAppend, case_fileAppend, kmz_fileAppend, \ shp_fileAppend, ascii_fileAppend, mesh_units, kmz_mesh_units, \ shp_mesh_units, ascii_mesh_units, pdf_fileAppend, pdf_mesh_units; - - boost::local_time::local_time_facet* timeOutputFacet; timeOutputFacet = new boost::local_time::local_time_facet(); //NOTE: WEIRD ISSUE WITH THE ABOVE 2 LINES OF CODE! DO NOT CALL DELETE ON THIS BECAUSE THE LOCALE OBJECT BELOW DOES. @@ -2226,25 +2225,19 @@ void NinjaFoam::SetOutputFilenames() ascii_mesh_units = lengthUnits::getString( input.velOutputFileDistanceUnits ); pdf_mesh_units = lengthUnits::getString( input.pdfUnits ); - ostringstream os, os_kmz, os_shp, os_ascii, os_pdf; - std::ostringstream os_case; - os_case << rootFile << "_" << timeAppend << "_FOAM"; + ostringstream os, os_case, os_kmz, os_shp, os_ascii, os_pdf; if( input.initializationMethod == WindNinjaInputs::domainAverageInitializationFlag ){ double tempSpeed = input.inputSpeed; velocityUnits::fromBaseUnits(tempSpeed, input.inputSpeedUnits); os << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); + os_case << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_kmz << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_shp << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_ascii << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); os_pdf << "_" << (long) (input.inputDirection+0.5) << "_" << (long) (tempSpeed+0.5); - os_case << "_DA"; - } - if( input.initializationMethod == WindNinjaInputs::wxModelInitializationFlag){ - os_case << "_WxModel"; } - double meshResolutionTemp = input.dem.get_cellSize(); double kmzResolutionTemp = input.kmzResolution; double shpResolutionTemp = input.shpResolution; @@ -2260,30 +2253,20 @@ void NinjaFoam::SetOutputFilenames() lengthUnits::fromBaseUnits(pdfResolutionTemp, input.pdfUnits); os << "_" << timeAppend << (long) (meshResolutionTemp+0.5) << mesh_units; + os_case << "_" << timeAppend << (long) (meshResolutionTemp+0.5) << mesh_units; os_kmz << "_" << timeAppend << (long) (kmzResolutionTemp+0.5) << kmz_mesh_units; os_shp << "_" << timeAppend << (long) (shpResolutionTemp+0.5) << shp_mesh_units; os_ascii << "_" << timeAppend << (long) (velResolutionTemp+0.5) << ascii_mesh_units; os_pdf << "_" << timeAppend << (long) (pdfResolutionTemp+0.5) << pdf_mesh_units; - - fileAppend = os.str(); + case_fileAppend = os_case.str(); kmz_fileAppend = os_kmz.str(); shp_fileAppend = os_shp.str(); ascii_fileAppend = os_ascii.str(); pdf_fileAppend = os_pdf.str(); - - os_case << "_munit" << mesh_units; - - os_case << "_kmz" << (long)(kmzResolutionTemp + 0.5) << kmz_mesh_units - << "_shp" << (long)(shpResolutionTemp + 0.5) << shp_mesh_units - << "_ascii" << (long)(velResolutionTemp + 0.5) << ascii_mesh_units - << "_pdf" << (long)(pdfResolutionTemp + 0.5) << pdf_mesh_units; - - - // Assign final casefilenam - casefilenamefoam = os_case.str(); + casefilename = rootFile + case_fileAppend + ".ninja"; input.kmlFile = rootFile + kmz_fileAppend + ".kml"; input.kmzFile = rootFile + kmz_fileAppend + ".kmz"; @@ -2742,7 +2725,7 @@ void NinjaFoam::writeMassMeshVtkOutput() CaseFile casefile; if (casefile.getZipOpen()) { - casefile.rename(casefilenamefoam); + casefile.rename(casefilename); std::string directoryPath = get_outputPath(); std::string normfile = casefile.parse("file", massMeshVtkFilename); std::string directoryofVTK = casefile.parse("directory", massMeshVtkFilename); From 47bd9debd4126784da12d3423c8bf2a3ce8c2b23 Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 13 Mar 2025 13:56:38 -0600 Subject: [PATCH 15/35] fixed difference in mesh resolution calculated and shown in the gui vs the actual mesh, which resulted in the output files having differing names in the mesh resolution part from the case file names. This fix also makes the gui and cli mesh resolutions finally consistent. For issue #564 and #7 --- src/gui/mainWindow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index a98428cd..660753bc 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1596,7 +1596,7 @@ int mainWindow::checkInputFile(QString fileName) //get the geo-transform if(poInputDS->GetGeoTransform(adfGeoTransform) == CE_None) { - int c1, c2; + double c1, c2; c1 = adfGeoTransform[1]; c2 = adfGeoTransform[5]; if(abs(c1) == abs(c2)) @@ -3828,13 +3828,13 @@ int mainWindow::checkGoogleItem() { if(checkSurfaceItem() != red) { - if((int)noGoogleCellSize > tree->google->googleResSpinBox->value()) + if(noGoogleCellSize > tree->google->googleResSpinBox->value()) { tree->googleItem->setIcon(0, tree->caution); tree->googleItem->setToolTip(0, "The resolution of the google file may be too fine."); status = amber; } - else if((int)GDALCellSize > tree->google->googleResSpinBox->value()) + else if(GDALCellSize > tree->google->googleResSpinBox->value()) { tree->googleItem->setIcon(0, tree->caution); tree->googleItem->setToolTip(0, "The output resolution is finer than the DEM resolution"); @@ -3878,7 +3878,7 @@ int mainWindow::checkFbItem() { if(checkSurfaceItem() == green || checkSurfaceItem() == amber) { - if((int)GDALCellSize > tree->fb->fbResSpinBox->value()) + if(GDALCellSize > tree->fb->fbResSpinBox->value()) { tree->fbItem->setIcon(0, tree->caution); tree->fbItem->setToolTip(0, "The output resolutions is finer than the DEM resolution"); @@ -3923,7 +3923,7 @@ int mainWindow::checkShapeItem() status = amber; } */ - if((int)GDALCellSize > tree->shape->shapeResSpinBox->value()) + if(GDALCellSize > tree->shape->shapeResSpinBox->value()) { tree->shapeItem->setIcon(0, tree->caution); tree->shapeItem->setToolTip(0, "The output resolutions is finer than the DEM resolution"); @@ -3967,7 +3967,7 @@ int mainWindow::checkPdfItem() status = amber; } */ - if((int)GDALCellSize > tree->pdf->pdfResSpinBox->value()) + if(GDALCellSize > tree->pdf->pdfResSpinBox->value()) { tree->pdfItem->setIcon(0, tree->caution); tree->pdfItem->setToolTip(0, "The output resolutions is finer than the DEM resolution"); From 7e353d8fbd03a270db1dabbfd21c71c6f812450d Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 17 Mar 2025 19:34:38 -0600 Subject: [PATCH 16/35] 1st cleanup attempt of casefile stuff, plus make casefile renaming only be for the 1st run/ninja, rather than letting it rename each run/ninja till the casefile ends with the final run/ninja casefile name rather than the 1st run/ninja casefile name. For issue #7 --- src/gui/mainWindow.cpp | 1257 ++++++++++++++++++--------------------- src/gui/mainWindow.h | 12 +- src/ninja/casefile.cpp | 25 +- src/ninja/casefile.h | 4 +- src/ninja/cli.cpp | 93 ++- src/ninja/cli.h | 12 +- src/ninja/ninja.cpp | 112 ++-- src/ninja/ninja.h | 5 +- src/ninja/ninjafoam.cpp | 76 +-- src/ninja/ninjafoam.h | 8 +- 10 files changed, 741 insertions(+), 863 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 660753bc..74402d4e 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1653,68 +1653,51 @@ void mainWindow::openOutputPath() } } - - -std::vector mainWindow::split(const std::string &s, const std::string &delimiter) { - std::vector tokens; - size_t start = 0; - size_t end = s.find(delimiter); - while (end != std::string::npos) { - tokens.push_back(s.substr(start, end - start)); - start = end + delimiter.length(); - end = s.find(delimiter, start); - } - tokens.push_back(s.substr(start, end)); - return tokens; -} - - int mainWindow::solve() { - bool writeCF = tree->solve->CaseFIBOX->isChecked(); + bool writeCF = tree->solve->CaseFIBOX->isChecked(); + + CaseFile casefile; - CaseFile casefile; std::string getdir = tree->solve->outputDirectory().toStdString(); - std::string inputpath = getdir + "/config.cfg"; + + std::string getfileName = casefile.parse("file", inputFileName.toStdString()); + std::string stationCSVFILEPATH = getdir + "/selectedstations.csv"; - std::string getfileName = casefile.parse("file", inputFileName.toStdString()); - std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; - casefile.setdir(getdir); - casefile.setzip(zipFilePath); + std::string zipFilePath = getdir + "/tmp.ninja"; + + casefile.setZipOpen(true); + casefile.setdir(getdir); + casefile.setzip(zipFilePath); std::ofstream outFile(inputpath); std::ofstream stationCSVFILE(stationCSVFILEPATH); - if (!outFile) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; } - + if (!stationCSVFILE) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; } - if (!writeCF) { + if (!writeCF) { outFile.close(); - stationCSVFILE.close(); + stationCSVFILE.close(); casefile.setZipOpen(false); - casefile.deleteFileFromPath(getdir, "config.cfg"); - - casefile.deleteFileFromPath(getdir, "selectedstations.csv"); - } - else { - casefile.setZipOpen(true); + casefile.deleteFileFromPath(getdir, "config.cfg"); + casefile.deleteFileFromPath(getdir, "selectedstations.csv"); } #ifdef NINJAFOAM bool useNinjaFoam = tree->ninjafoam->ninjafoamGroupBox->isChecked(); - if (useNinjaFoam && writeCF) { + if (writeCF && useNinjaFoam) { outFile << "--momentum_flag true\n"; } #endif @@ -1725,109 +1708,104 @@ int mainWindow::solve() std::string demFile = inputFileName.toStdString(); if (writeCF) { - if (casefile.getDownloadedFromDEM() == true) { - std::vector vec = casefile.getBoundingBox(); - - outFile << "--fetch_elevation true" << "\n"; - outFile << "--north " << vec[0] << "\n"; - - outFile << "--south " << vec[1] << "\n"; - - outFile << "--west " << vec[2] << "\n"; - outFile << "--east " << vec[3] << "\n"; - - outFile << "--elevation_source " << casefile.getElevSource() << "\n"; - - } - else { - outFile << "--fetch_elevation false" << "\n"; + if (casefile.getDownloadedFromDEM() == true) + { + std::vector vec = casefile.getBoundingBox(); + outFile << "--fetch_elevation true" << "\n"; + outFile << "--north " << vec[0] << "\n"; + outFile << "--south " << vec[1] << "\n"; + outFile << "--west " << vec[2] << "\n"; + outFile << "--east " << vec[3] << "\n"; + outFile << "--elevation_source " << casefile.getElevSource() << "\n"; + } else + { + outFile << "--fetch_elevation false" << "\n"; } outFile << "--elevation_file " << demFile << "\n"; } - + #ifdef NINJAFOAM std::string caseFile = existingCaseDir.toStdString(); - if (useNinjaFoam && writeCF) { - outFile << "--existing_case_directory" << caseFile<< "\n"; + if (writeCF && useNinjaFoam) { + outFile << "--existing_case_directory" << caseFile << "\n"; } - #endif //vegetation/roughness int vegIndex = tree->surface->roughnessComboBox->currentIndex(); WindNinjaInputs::eVegetation vegetation; - if( inputFileType != LCP ) { - //get choice from combo - if(vegIndex == 0) { - vegetation = WindNinjaInputs::grass; - if (writeCF) { - outFile << "--vegetation grass\n"; - } - } - else if( vegIndex == 1 ) { - vegetation = WindNinjaInputs::brush; - if (writeCF) { - outFile << "--vegetation brush\n"; - } - } - else if( vegIndex == 2 ) { - vegetation = WindNinjaInputs::trees; - if (writeCF) { - outFile << "--vegetation trees\n"; + if( inputFileType != LCP ) + { + //get choice from combo + if(vegIndex == 0) + { + vegetation = WindNinjaInputs::grass; + if (writeCF) { + outFile << "--vegetation grass\n"; + } + } else if( vegIndex == 1 ) + { + vegetation = WindNinjaInputs::brush; + if (writeCF) { + outFile << "--vegetation brush\n"; + } + } else if( vegIndex == 2 ) + { + vegetation = WindNinjaInputs::trees; + if (writeCF) { + outFile << "--vegetation trees\n"; + } } } - } - //mesh do resolution later + + //mesh int meshIndex = tree->surface->meshResComboBox->currentIndex(); Mesh::eMeshChoice meshChoice; double meshRes; lengthUnits::eLengthUnits meshUnits; bool customMesh = false; - if( meshIndex == 0 ) { + if( meshIndex == 0 ) + { meshChoice = Mesh::coarse; if (writeCF) { outFile << "--mesh_choice coarse\n"; } - } - else if( meshIndex == 1 ) { + } else if( meshIndex == 1 ) + { meshChoice = Mesh::medium; - if (writeCF) { outFile << "--mesh_choice medium\n"; } - } - else if( meshIndex == 2 ) { + } else if( meshIndex == 2 ) + { meshChoice = Mesh::fine; - if (writeCF) { outFile << "--mesh_choice fine\n"; } - } - else { - meshRes = tree->surface->meshResDoubleSpinBox->value(); - customMesh = true; + } else + { + meshRes = tree->surface->meshResDoubleSpinBox->value(); + customMesh = true; } - if( tree->surface->meshFeetRadioButton->isChecked() ) { + if( tree->surface->meshFeetRadioButton->isChecked() ) + { meshUnits = lengthUnits::feet; if (writeCF) { outFile << "--units_mesh_resolution ft\n"; } - - } - else { + } else + { meshUnits = lengthUnits::meters; if (writeCF) { outFile << "--units_mesh_resolution m\n"; } } - if (customMesh && writeCF) { - outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; + if (writeCF && customMesh) { + outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; } - - #ifdef NINJAFOAM WindNinjaInputs::eNinjafoamMeshChoice ninjafoamMeshChoice; if(useNinjaFoam){ @@ -1868,251 +1846,244 @@ int mainWindow::solve() QVariant temp = tree->surface->timeZone->tzComboBox->itemData( tzIndex ); std::string timeZone = temp.toString().toStdString(); - if (writeCF) { - outFile << "--time_zone " << timeZone <<"\n"; + outFile << "--time_zone " << timeZone << "\n"; } //diurnal bool useDiurnal = tree->diurnal->diurnalGroupBox->isChecked(); - //stability bool useStability = tree->stability->stabilityGroupBox->isChecked(); - + if (writeCF) { - if (useDiurnal == 0) { + if (useDiurnal == 0) + { outFile << "--diurnal_winds false\n"; - } - else { + } else + { outFile << "--diurnal_winds true\n"; } - if (useStability == 0) { + if (useStability == 0) + { outFile << "--non_neutral_stability false\n"; - } - else { - + } else + { outFile << "--non_neutral_stability true\n"; } } + //initialization method WindNinjaInputs::eInitializationMethod initMethod; - if( tree->wind->windGroupBox->isChecked() ) { + if( tree->wind->windGroupBox->isChecked() ) + { initMethod = WindNinjaInputs::domainAverageInitializationFlag; - if (writeCF) { - outFile << "--initialization_method domainAverageInitialization\n"; + outFile << "--initialization_method domainAverageInitialization\n"; } - } - else if( tree->point->pointGroupBox->isChecked() ) { + } else if( tree->point->pointGroupBox->isChecked() ) + { initMethod = WindNinjaInputs::pointInitializationFlag; - if (writeCF) { - outFile << "--initialization_method pointInitialization\n"; + outFile << "--initialization_method pointInitialization\n"; } - } - else if( tree->weather->weatherGroupBox->isChecked() ) { + } else if( tree->weather->weatherGroupBox->isChecked() ) + { initMethod = WindNinjaInputs::wxModelInitializationFlag; - if (writeCF) { - outFile << "--initialization_method wxModelInitialization\n" ; + outFile << "--initialization_method wxModelInitialization\n"; } } - - - + //input wind height double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); - lengthUnits::eLengthUnits inHeightUnits; - if (writeCF) { - outFile << "--input_wind_height " << std::to_string(inHeight) << "\n" ; + outFile << "--input_wind_height " << std::to_string(inHeight) << "\n"; } - if(tree->wind->metaWind->feetRadioButton->isChecked()) { - inHeightUnits = lengthUnits::feet; - - if (writeCF) { - outFile << "--units_input_wind_height ft\n"; - } + lengthUnits::eLengthUnits inHeightUnits; + if(tree->wind->metaWind->feetRadioButton->isChecked()) + { + inHeightUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_input_wind_height ft\n"; + } + } else + { + inHeightUnits = lengthUnits::meters; + if (writeCF) { + outFile << "--units_input_wind_height m\n"; + } } - else { - inHeightUnits = lengthUnits::meters; - if (writeCF) { - outFile << "--units_input_wind_height m\n"; - } - } - // handle widget download DEM in widgetdownloadDEM.cpp //speed units and air temp units velocityUnits::eVelocityUnits inputSpeedUnits; - if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) { - inputSpeedUnits = velocityUnits::milesPerHour; - - if (writeCF) { - outFile << "--input_speed_units mph\n" ; - } - } - else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) { - inputSpeedUnits = velocityUnits::metersPerSecond; - - if (writeCF) { - outFile << "--input_speed_units mps\n"; - } - } - else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) { - inputSpeedUnits = velocityUnits::knots; - - if (writeCF) { - outFile << "--input_speed_units kts\n"; - } - } - else { - inputSpeedUnits = velocityUnits::kilometersPerHour; - - if (writeCF) { - outFile << "--input_speed_units kph\n" ; - } + if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) + { + inputSpeedUnits = velocityUnits::milesPerHour; + if (writeCF) { + outFile << "--input_speed_units mph\n"; + } + } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) + { + inputSpeedUnits = velocityUnits::metersPerSecond; + if (writeCF) { + outFile << "--input_speed_units mps\n"; + } + } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) + { + inputSpeedUnits = velocityUnits::knots; + if (writeCF) { + outFile << "--input_speed_units kts\n"; + } + } else + { + inputSpeedUnits = velocityUnits::kilometersPerHour; + if (writeCF) { + outFile << "--input_speed_units kph\n" ; + } } - temperatureUnits::eTempUnits tempUnits; - if(tree->wind->windTable->airTempUnits->currentIndex() == 0) + temperatureUnits::eTempUnits tempUnits; + if(tree->wind->windTable->airTempUnits->currentIndex() == 0) { - tempUnits = temperatureUnits::F; - - if (writeCF) { - outFile << "--air_temp_units F\n" ; - } + tempUnits = temperatureUnits::F; + if (writeCF) { + outFile << "--air_temp_units F\n" ; + } + } else if(tree->wind->windTable->airTempUnits->currentIndex() == 1) + { + tempUnits = temperatureUnits::C; + if (writeCF) { + outFile << "--air_temp_units C\n"; + } } - else if(tree->wind->windTable->airTempUnits->currentIndex() == 1){ - tempUnits = temperatureUnits::C; - if (writeCF) { - outFile << "--air_temp_units C\n"; - } - } //model init std::string weatherFile; QModelIndex mi = tree->weather->treeView->selectionModel()->currentIndex(); - if( mi.isValid() ) { - QFileInfo fi( tree->weather->model->fileInfo( mi ) ); - weatherFile = fi.absoluteFilePath().toStdString(); - - if (writeCF) { - outFile << "--wx_model_type "; - outFile << "--forecast_duration "<< tree->weather->hourSpinBox->value() <<"\n"; - } + if( mi.isValid() ) + { + QFileInfo fi( tree->weather->model->fileInfo( mi ) ); + weatherFile = fi.absoluteFilePath().toStdString(); + if (writeCF) { + outFile << "--wx_model_type "; + outFile << "--forecast_duration " << tree->weather->hourSpinBox->value() << "\n"; + } + } else + { + weatherFile = ""; } - else - weatherFile = ""; //output height double outHeight = tree->output->outputHeight->outputHeightDoubleSpinBox->value(); - lengthUnits::eLengthUnits outHeightUnits; - if (writeCF) { - outFile << "--output_wind_height " <output->outputHeight->feetRadioButton->isChecked()) { - - if (writeCF) { - outFile << "--units_output_wind_height ft\n"; - - } - outHeightUnits = lengthUnits::feet; - } - else { - outHeightUnits = lengthUnits::meters; - - if (writeCF) { - outFile << "--units_output_wind_height m\n";} + lengthUnits::eLengthUnits outHeightUnits; + if(tree->output->outputHeight->feetRadioButton->isChecked()) + { + outHeightUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_output_wind_height ft\n"; + } + } else + { + outHeightUnits = lengthUnits::meters; + if (writeCF) { + outFile << "--units_output_wind_height m\n"; + } } velocityUnits::eVelocityUnits outputSpeedUnits; - if(tree->output->outputSpeedUnitsCombo->currentIndex() == 0) { + if(tree->output->outputSpeedUnitsCombo->currentIndex() == 0) + { outputSpeedUnits = velocityUnits::milesPerHour; - - if (writeCF) { - outFile << "--output_speed_units mph\n"; } - } - else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) { + if (writeCF) { + outFile << "--output_speed_units mph\n"; + } + } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) + { outputSpeedUnits = velocityUnits::metersPerSecond; - - if (writeCF) { - outFile << "--output_speed_units mps\n" ; } - } - else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) { + if (writeCF) { + outFile << "--output_speed_units mps\n" ; + } + } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) + { outputSpeedUnits = velocityUnits::kilometersPerHour; - - if (writeCF) { - outFile << "--output_speed_units kph\n"; } - } - else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) { + if (writeCF) { + outFile << "--output_speed_units kph\n"; + } + } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) + { outputSpeedUnits = velocityUnits::knots; - if (writeCF) { - outFile << "--output_speed_units kts\n"; } + outFile << "--output_speed_units kts\n"; + } } //clip buffer? int clip = tree->output->bufferSpinBox->value(); - + if (writeCF) { + //if (clip > 0) + //{ + outFile << "--output_buffer_clipping " << std::to_string(clip) << "\n"; + //} + } + bool writeWxOutput; if( tree->output->wxModelOutputCheckBox->isEnabled() ) writeWxOutput = tree->output->wxModelOutputCheckBox->isChecked(); //google bool writeGoogle = tree->google->googleGroupBox->isChecked(); - + double googleRes = tree->google->googleResSpinBox->value(); if (writeCF) { - if (writeGoogle) { - outFile << "--write_goog_output true\n"; - if( initMethod == WindNinjaInputs::wxModelInitializationFlag) { - - outFile << "--write_wx_model_goog_output true\n"; - } + if (writeGoogle) + { + outFile << "--write_goog_output true\n"; + if( initMethod == WindNinjaInputs::wxModelInitializationFlag) + { + outFile << "--write_wx_model_goog_output true\n"; + } + outFile << "--goog_out_resolution " << std::to_string(googleRes) << "\n"; } - if (clip) { - outFile << "output_buffer_clipping true\n"; } - } - - - double googleRes = tree->google->googleResSpinBox->value(); - if (writeCF) { - outFile << "--goog_out_resolution " << std::to_string(googleRes)<< "\n"; } double vectorWidth = tree->google->vectorWidthDoubleSpinBox->value(); lengthUnits::eLengthUnits googleUnits; KmlVector::egoogSpeedScaling googleScale; //bool writeLegend = tree->google->legendGroupBox->isChecked(); - if(tree->google->googleMetersRadioButton->isChecked()) { - googleUnits = lengthUnits::meters; - - if (writeCF) { - outFile << "--units_goog_out_resolution m\n"; } + if(tree->google->googleMetersRadioButton->isChecked()) + { + googleUnits = lengthUnits::meters; + if (writeCF) { + outFile << "--units_goog_out_resolution m\n"; + } + } else + { + googleUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_goog_out_resolution ft\n"; + } } - else { - googleUnits = lengthUnits::feet; - if (writeCF) { - outFile << "--units_goog_out_resolution ft\n"; } + if(tree->google->uniformRangeRadioButton->isChecked()) + { + googleScale = KmlVector::equal_interval; + } else + { + googleScale = KmlVector::equal_color; } - if(tree->google->uniformRangeRadioButton->isChecked()) - googleScale = KmlVector::equal_interval; - else - googleScale = KmlVector::equal_color; std::string googleScheme; bool googVectorScaling = tree->google->applyVectorScaling->isChecked(); - if (writeCF) { - if (googVectorScaling) { - - outFile << "--goog_out_vector_scaling true\n"; - } - else { - - outFile << "--goog_out_vector_scaling false\n"; + if (googVectorScaling) + { + outFile << "--goog_out_vector_scaling true\n"; + } else + { + outFile << "--goog_out_vector_scaling false\n"; } } if(tree->google->colorblindBox->isChecked()) @@ -2124,100 +2095,104 @@ int mainWindow::solve() if (googCheckScheme=="Default") { googleScheme="default"; - if (writeCF) { - outFile << "--goog_out_color_scheme ROYGB\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme ROYGB\n"; + } } if (googCheckScheme=="ROPGW (Red Orange Pink Green White)") { googleScheme="ROPGW"; - - if (writeCF) { - outFile << "--goog_out_color_scheme ROPGW\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme ROPGW\n"; + } } if (googCheckScheme=="Oranges") { googleScheme="oranges"; - - if (writeCF) { - outFile << "--goog_out_color_scheme oranges\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme oranges\n"; + } } if (googCheckScheme=="Blues") { googleScheme="blues"; - - if (writeCF) { - outFile << "--goog_out_color_scheme blues\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme blues\n"; + } } if (googCheckScheme=="Pinks") { googleScheme="pinks"; - - if (writeCF) { - outFile << "--goog_out_color_scheme pinks\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme pinks\n"; + } } if (googCheckScheme=="Greens") { googleScheme="greens"; - - if (writeCF) { - outFile << "--goog_out_color_scheme greens\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme greens\n"; + } } if (googCheckScheme=="Magic Beans") { googleScheme="magic_beans"; - - if (writeCF) { - outFile << "--goog_out_color_scheme magic_beans\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme magic_beans\n"; + } } if (googCheckScheme=="Pink to Green") { googleScheme="pink_to_green"; - - if (writeCF) { - outFile << "--goog_out_color_scheme pink_to_green\n"; } + if (writeCF) { + outFile << "--goog_out_color_scheme pink_to_green\n"; + } } - } - else + } else { googleScheme="default"; - if (writeCF) { - outFile << "--goog_out_color_scheme ROYGB\n"; } + outFile << "--goog_out_color_scheme ROYGB\n"; + } } + //ascii raster fb files bool writeFb = tree->fb->fbGroupBox->isChecked(); double fbRes = tree->fb->fbResSpinBox->value(); - if (writeCF) { - - if (writeFb) { - outFile << "--write_ascii_output true\n"; + if (writeFb) + { + outFile << "--write_ascii_output true\n"; + if (initMethod == WindNinjaInputs::wxModelInitializationFlag ) + { + outFile << "--write_wx_model_ascii_output true\n"; + } + outFile << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; } - - if (writeFb && initMethod == WindNinjaInputs::wxModelInitializationFlag ) { - - outFile << "--write_wx_model_ascii_output true\n"; - - - } - outFile << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; - } - lengthUnits::eLengthUnits fbUnits; - if(tree->fb->fbMetersRadioButton->isChecked()) { - fbUnits = lengthUnits::meters; - if (writeCF) { - outFile << "--units_ascii_out_resolution m\n"; } - } - else { - fbUnits = lengthUnits::feet; - if (writeCF) { - outFile << "--units_ascii_out_resolution ft\n"; } + if(tree->fb->fbMetersRadioButton->isChecked()) + { + fbUnits = lengthUnits::meters; + if (writeCF) { + outFile << "--units_ascii_out_resolution m\n"; + } + } else + { + fbUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_ascii_out_resolution ft\n"; + } } + //write atmosphere file? bool writeAtm = tree->fb->atmFileCheckBox->isChecked(); - + if (writeCF) { + if (writeAtm) + { + outFile << "--write_farsite_atm true\n"; + } + } if(writeAtm && writeFb) { if((outHeight == 20 && outHeightUnits == lengthUnits::feet && @@ -2241,87 +2216,73 @@ int mainWindow::solve() return false; } } - //shape bool writeShape = tree->shape->shapeGroupBox->isChecked(); - // do for wx - - + // do for wx double shapeRes = tree->shape->shapeResSpinBox->value(); - - if (writeCF) { - if (writeAtm) { - outFile << "--write_farsite_atm true\n"; - } - if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) { - - if (writeShape) { - outFile << "--write_wx_model_shapefile_output true\n"; - } - else { - outFile << "--write_wx_model_shapefile_output false\n"; + if (writeCF) { + if (writeShape) + { + outFile << "--write_shapefile_output true\n"; + if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) + { + outFile << "--write_wx_model_shapefile_output true\n"; + } + outFile << "--shape_out_resolution " << std::to_string(shapeRes) << "\n"; } } - else { - if (writeShape) { - outFile << "--write_shapefile_output true\n"; - } - else { - outFile << "--write_shapefile_output false\n"; - } + lengthUnits::eLengthUnits shapeUnits; + if(tree->shape->shapeMetersRadioButton->isChecked()) + { + shapeUnits = lengthUnits::meters; + if (writeCF) { + outFile << "--units_shape_out_resolution m\n"; + } + } else + { + shapeUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_shape_out_resolution ft\n"; + } } - outFile << "--shape_out_resolution " <shape->shapeMetersRadioButton->isChecked()) { - shapeUnits = lengthUnits::meters; - if (writeCF) { - outFile << "--units_shape_out_resolution m\n"; } - } - else{ - shapeUnits = lengthUnits::feet; - if (writeCF) { - outFile << "--units_shape_out_resolution ft\n"; } - } //pdf bool writePdf = tree->pdf->pdfGroupBox->isChecked(); - double pdfRes = tree->pdf->pdfResSpinBox->value(); double pdfLineWidth = tree->pdf->vectorWidthDoubleSpinBox->value(); - + if (writeCF) { + if (writePdf) + { + outFile << "--write_pdf_output true\n"; + outFile << "--pdf_out_resolution "<< std::to_string(pdfRes) << "\n"; + outFile << "--pdf_linewidth "<< std::to_string(pdfLineWidth) << "\n"; + } + } lengthUnits::eLengthUnits pdfUnits; - if(tree->pdf->pdfMetersRadioButton->isChecked()) { - if (writeCF) { - outFile << "--units_pdf_out_resolution m\n"; } + if(tree->pdf->pdfMetersRadioButton->isChecked()) + { pdfUnits = lengthUnits::meters; - } - else { - - if (writeCF) { - outFile << "--units_pdf_out_resolution ft\n"; } - pdfUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_pdf_out_resolution m\n"; + } + } else + { + pdfUnits = lengthUnits::feet; + if (writeCF) { + outFile << "--units_pdf_out_resolution ft\n"; + } } int pdfBase = tree->pdf->backgroundComboBox->currentIndex(); - if (writeCF) { - if (writePdf) { - outFile << "--write_pdf_output true\n"; - } - else { - outFile << "--write_pdf_output false\n"; - } - outFile << "--pdf_out_resolution "<< std::to_string(pdfRes) <<"\n"; - outFile << "--pdf_linewidth "<pdf->sizeComboBox->currentIndex(); // Letter @@ -2329,26 +2290,27 @@ int mainWindow::solve() { pdfHeight = 11.0; pdfWidth = 8.5; - if (writeCF) { - outFile << "--pdf_size letter\n" ;} + if (writeCF) { + outFile << "--pdf_size letter\n"; + } } // Legal else if( pdfSize == 1 ) { pdfHeight = 14.0; pdfWidth = 8.5; - - if (writeCF) { - outFile << "--pdf_size legal\n";} + if (writeCF) { + outFile << "--pdf_size legal\n"; + } } // Tabloid else if( pdfSize == 2 ) { pdfHeight = 17.0; pdfWidth = 11.0; - - if (writeCF) { - outFile << "--pdf_size tabloid\n";} + if (writeCF) { + outFile << "--pdf_size tabloid\n"; + } } if( tree->pdf->landscapeRadioButton->isChecked() ) { @@ -2359,26 +2321,25 @@ int mainWindow::solve() } bool writeVTK = tree->vtk->vtkGroupBox->isChecked(); - - + if (writeCF) { + if (writeVTK) + { + outFile << "--write_vtk_output true\n"; + } + } + //number of processors int nThreads = tree->solve->numProcSpinBox->value(); - -if (writeCF) { - outFile << "--num_threads " <point->enableTimeseries; //Find out if its a timeseries run or not bool writeStationKML = tree->point->writeStationKmlButton->isChecked(); //Write a kml file bool writeStationCSV = tree->point->writeStationFileButton->isChecked(); //hidden for now - std::vector fullFileListPoint = tree->point->fullFileList; - if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true && writeCF) { - - // for each file append it to csv - // if any point file is under a wx station folder just copy the entire folder over - otherwise no - - outFile << "--fetch_station true\n"; - outFile << "--fetch_type "<< tree->point->xWidget->getType()<< "\n"; - if (tree->point->xWidget->getType() == "bbox") { - outFile << "--station_buffer " <point->xWidget->getBuffer()<< "\n" ; - outFile << "--station_buffer_units " << tree->point->xWidget->getBufferUnits()<< "\n"; - } - if (tree->point->xWidget->getType() == "stid") { - outFile << "--fetch_station_name " << tree->point->xWidget->getStationIDS() << "\n"; - } - if (tree->point->xWidget->getTimeseries() == false) { - outFile << "--fetch_current_station_data false\n"; - outFile << "--number_time_steps " << std::to_string(numTimeSteps) <<"\n"; - } - else { - outFile << "--fetch_current_station_data true\n"; - } - - if (writeStationKML) { - - outFile << "--write_wx_station_kml true\n"; - } - else { - outFile << "--write_wx_station_kml false\n"; - - } - if (writeStationCSV) { - outFile << "--write_wx_station_csv true\n"; - } - else { - outFile << "--write_wx_station_csv false\n"; - - } - - - } - - else if (writeCF) { - outFile << "--fetch_station false\n"; - if (useTimeList) { - - outFile << "--fetch_current_station_data false\n"; - - outFile << "--start_year " << xStartTime[0] << "\n"; - outFile << "--start_month " <point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true) + { + outFile << "--fetch_station true\n"; + outFile << "--fetch_type " << tree->point->xWidget->getType() << "\n"; + if (tree->point->xWidget->getType() == "bbox") + { + outFile << "--station_buffer " << tree->point->xWidget->getBuffer() << "\n"; + outFile << "--station_buffer_units " << tree->point->xWidget->getBufferUnits() << "\n"; + } + if (tree->point->xWidget->getType() == "stid") + { + outFile << "--fetch_station_name " << tree->point->xWidget->getStationIDS() << "\n"; + } + if (tree->point->xWidget->getTimeseries() == false) + { + outFile << "--fetch_current_station_data false\n"; + outFile << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + } else + { + outFile << "--fetch_current_station_data true\n"; + } + } else // if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true) + { + outFile << "--fetch_station false\n"; + if (useTimeList) + { + outFile << "--fetch_current_station_data false\n"; + outFile << "--start_year " << xStartTime[0] << "\n"; + outFile << "--start_month " << xStartTime[1] << "\n"; + outFile << "--start_day " << xStartTime[2] << "\n"; + outFile << "--start_hour " << xStartTime[3] << "\n"; + outFile << "--start_minute " << xStartTime[4] << "\n"; + outFile << "--stop_year " << xEndTime[0] << "\n"; + outFile << "--stop_month " << xEndTime[1] << "\n"; + outFile << "--stop_day " << xEndTime[2] << "\n"; + outFile << "--stop_hour " << xEndTime[3] << "\n"; + outFile << "--stop_minute " << xEndTime[4] << "\n"; + outFile << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + } else + { + outFile << "--fetch_current_station_data true\n"; + } + } // if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true) - if ((writeCF) ) { + if (writeStationKML) + { + outFile << "--write_wx_station_kml true\n"; + } else + { + outFile << "--write_wx_station_kml false\n"; + } + if (writeStationCSV) + { + outFile << "--write_wx_station_csv true\n"; + } else + { + outFile << "--write_wx_station_csv false\n"; + } - for (std::string & pfile : fullFileListPoint) { - std::vector tokens = split(pfile, "/"); - - if (tokens.size() >= 2) { - std::string secondToLastToken = tokens[tokens.size()-2]; - - std::string pointpath1 = "pointinitialization/" + tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1] ; - std::string pointpath2 = "pointinitialization/" + tokens[tokens.size()-1] ; - if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - casefile.addFileToZip(zipFilePath, getdir, pointpath1, pfile); - } - else { - casefile.addFileToZip(zipFilePath , getdir, pointpath2, pfile); - } + // for each file append it to csv + // if any point file is under a wx station folder just copy the entire folder over - otherwise no + std::vector fullFileListPoint = tree->point->fullFileList; + for (std::string & pfile : fullFileListPoint) + { + std::vector tokens = split(pfile, "/"); + if (tokens.size() >= 2) + { + std::string secondToLastToken = tokens[tokens.size()-2]; + std::string pointpath1 = "pointinitialization/" + tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1]; + std::string pointpath2 = "pointinitialization/" + tokens[tokens.size()-1]; + if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) + { + casefile.addFileToZip(zipFilePath, getdir, pointpath1, pfile); + } else + { + casefile.addFileToZip(zipFilePath, getdir, pointpath2, pfile); + } + } } - } - - for (std::string & pfile : pointFileList) { - std::vector tokens = split(pfile, "/"); - std::string updatedpath = casefile.parse("file", pfile); - if (tokens.size() >= 2) { - - std::string secondToLastToken = tokens[tokens.size()-2]; - if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - updatedpath = secondToLastToken + "/" + tokens[tokens.size() - 1]; - } - + // setup list of actually used/selected stations + for (std::string & pfile : pointFileList) + { + std::vector tokens = split(pfile, "/"); + std::string updatedpath = casefile.parse("file", pfile); + if (tokens.size() >= 2) + { + std::string secondToLastToken = tokens[tokens.size()-2]; + if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) + { + updatedpath = secondToLastToken + "/" + tokens[tokens.size() - 1]; + } + } + stationCSVFILE << updatedpath << "\n"; } + stationCSVFILE.close(); + std::string pointpathusual = "pointinitialization/selectedstations.csv"; + casefile.addFileToZip(zipFilePath, getdir, pointpathusual, stationCSVFILEPATH); - stationCSVFILE << updatedpath << "\n"; - } + } // if (writeCF) - stationCSVFILE.close(); - std::string pointpathusual = "pointinitialization/selectedstations.csv"; - casefile.addFileToZip(zipFilePath , getdir, pointpathusual , stationCSVFILEPATH); - - } /* - } * Note that pointFormat is not the same as stationFormat! * * point Format is based on pointInput::directStationTraffic @@ -2569,10 +2499,10 @@ if (writeCF) { boost::posix_time::ptime noTime; timeList.push_back(noTime); } - try{ - //Try to run windninja - if (writeCF) { - outFile << "--match_points true\n";} + try{ //Try to run windninja + if (writeCF) { + outFile << "--match_points true\n"; + } army->makeStationArmy(timeList,timeZone, pointFile, demFile, true,false); } catch(...){ //catch all exceptions and tell the user, prevent segfaults @@ -2629,9 +2559,9 @@ if (writeCF) { CPLDebug("STATION_FETCH","FILES STORED..."); try{ //try running with timelist - - if (writeCF) { - outFile << "--match_points true\n";} + if (writeCF) { + outFile << "--match_points true\n"; + } army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); //setting pointFileList[0] is just for header checks etc } catch(...){ //catch any and all exceptions and tell the user @@ -2665,9 +2595,9 @@ if (writeCF) { timeList.push_back(singleTime); pointInitialization::storeFileNames(pointFileList); try{ //try making the army with current data - - if (writeCF) { - outFile << "--match_points true\n";} + if (writeCF) { + outFile << "--match_points true\n"; + } army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); } catch(...){ //catch any and all exceptions and tell the user @@ -2743,10 +2673,10 @@ if (writeCF) { std::string baseMeta = baseDem+"-metadata"; std::string metaPath = std::string(CPLFormFilename(pathDem.c_str(),baseMeta.c_str(),".csv")); CPLDebug("STATION_FETCH","Saving Metadata to: %s",metaPath.c_str()); - if (writeCF) { - outFile << "--fetch_metadata true\n"; - outFile << "--metadata_filename" << metaPath<< "\n"; } + outFile << "--fetch_metadata true\n"; + outFile << "--metadata_filename" << metaPath << "\n"; + } pointInitialization::fetchMetaData(metaPath,demFile,true); } } @@ -2780,41 +2710,39 @@ if (writeCF) { } std::vector times = tree->weather->timeList(); - - - if ( times.size() > 0 ) { + /* This can throw a badForecastFile */ - if (writeCF) { + if (writeCF && times.size() > 0) + { std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - for (const auto& time : times) { - // Convert local_date_time to ptime using the UTC time zone - // Get the local time in the UTC time zone + for (const auto& time : times) + { + // Convert local_date_time to ptime using the UTC time zone + // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); - // Convert ptime to ISO 8601 string + // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); stringTimes.push_back(isoString); } - std::string outstr; - for (size_t i = 0; i < stringTimes.size(); ++i) - { - outstr += stringTimes[i]; - if (i != stringTimes.size() - 1) { - outstr += "||"; - } + std::string outstr; + for (size_t i = 0; i < stringTimes.size(); i++) + { + outstr += stringTimes[i]; + if (i != stringTimes.size() - 1) + { + outstr += "||"; + } } - outFile << "--forecast_times " << outstr <<"\n"; - - outFile << "--forecast_filename " << weatherFile << "\n"; - std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); - casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); - } - } - + outFile << "--forecast_times " << outstr << "\n"; + outFile << "--forecast_filename " << weatherFile << "\n"; + std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); + casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); + } // if (writeCF && times.size() > 0) try { @@ -2851,44 +2779,43 @@ if (writeCF) { delete army; return false; } - - //get times for casefile if no times are clicked by user - if (times.size() == 0 && writeCF) { + //get times for casefile if no times are clicked by user + if (writeCF && times.size() == 0) + { + std::vector wxtimesfromcasefile = casefile.getWXTIME(); + std::vector stringTimes; + blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - - std::vector wxtimesfromcasefile = casefile.getWXTIME(); - std::vector stringTimes; - blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - - for (const auto& time : wxtimesfromcasefile) { - // Convert local_date_time to ptime using the UTC time zone - // Get the local time in the UTC time zone - bpt::ptime pt = time.local_time_in(utc).local_time(); - - // Convert ptime to ISO 8601 string - std::string isoString = bpt::to_iso_string(pt); - stringTimes.push_back(isoString); - } + for (const auto& time : wxtimesfromcasefile) + { + // Convert local_date_time to ptime using the UTC time zone + // Get the local time in the UTC time zone + bpt::ptime pt = time.local_time_in(utc).local_time(); - std::string outstr; - for (size_t i = 0; i < stringTimes.size(); ++i) - { - outstr += stringTimes[i]; - if (i != stringTimes.size() - 1) { - outstr += "||"; - } - } + // Convert ptime to ISO 8601 string + std::string isoString = bpt::to_iso_string(pt); + stringTimes.push_back(isoString); + } - outFile << "--forecast_times " << outstr <<"\n"; - - outFile << "--forecast_filename " << weatherFile << "\n"; - std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); - casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); - } + std::string outstr; + for (size_t i = 0; i < stringTimes.size(); i++) + { + outstr += stringTimes[i]; + if (i != stringTimes.size() - 1) + { + outstr += "||"; + } + } + + outFile << "--forecast_times " << outstr << "\n"; + outFile << "--forecast_filename " << weatherFile << "\n"; + std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); + casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); + } // if (writeCF && times.size() == 0) nRuns = army->getSize(); - } + } // if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) progressDialog->setValue( 0 ); //set progress dialog and initial value @@ -2897,51 +2824,37 @@ if (writeCF) { std::string outputDir = tree->solve->outputDirectory().toStdString(); if (writeCF) { - outFile << "--output_path " << outputDir<< "\n" ; + outFile << "--output_path " << outputDir << "\n"; } if( outputDir == "" ) { // This should never happen, so if it does, fix it. throw( "no output directory specified in solve page" ); } - for(int i = 0;i < army->getSize(); i++) + //fill in the values + for(int i = 0;i < army->getSize(); i++) { - CPLSetConfigOption("CPL_DEBUG", "ON"); - - std::string domaininputpath = getdir + "/domainrun" + std::to_string(i) + ".cfg"; - - - std::ofstream domainRUNS(domaininputpath); + std::string domaininputpath = getdir + "/domainrun" + std::to_string(i) + ".cfg"; + std::ofstream domainRUNS(domaininputpath); // add runs to files - if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) + if (writeCF) { - if (writeCF) { - - domainRUNS << "--input_speed " << tree->wind->windTable->speed[i]->value() << "\n"; - - domainRUNS << "--input_direction " << tree->wind->windTable->dir[i]->value() << "\n"; - - domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; - - - domainRUNS << "--month " <wind->windTable->date[i]->date().month() << "\n"; - - domainRUNS << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; - - domainRUNS << "--hour " <wind->windTable->time[i]->time().hour() << "\n"; - - domainRUNS << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; - - domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; - domainRUNS << "--uni_cloud_cover " <wind->windTable->cloudCover[i]->value()<< "\n" ; - - domainRUNS << "--cloud_cover_units percent" << "\n" ; - } - + if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) + { + domainRUNS << "--input_speed " << tree->wind->windTable->speed[i]->value() << "\n"; + domainRUNS << "--input_direction " << tree->wind->windTable->dir[i]->value() << "\n"; + domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; + domainRUNS << "--month " << tree->wind->windTable->date[i]->date().month() << "\n"; + domainRUNS << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; + domainRUNS << "--hour " << tree->wind->windTable->time[i]->time().hour() << "\n"; + domainRUNS << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; + domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; + domainRUNS << "--uni_cloud_cover " << tree->wind->windTable->cloudCover[i]->value() << "\n"; + domainRUNS << "--cloud_cover_units percent" << "\n" ; + } } - army->setDEM( i, demFile ); #ifdef NINJAFOAM if(caseFile != ""){ @@ -2970,16 +2883,16 @@ if (writeCF) { else if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { //get speed - if (writeCF) { - outFile << "--input_speed " <wind->windTable->speed[i]->value()) << "\n"; } + if (writeCF) { + outFile << "--input_speed " << std::to_string(tree->wind->windTable->speed[i]->value()) << "\n"; + } army->setInputSpeed( i, tree->wind->windTable->speed[i]->value(), inputSpeedUnits); //get direction - - if (writeCF) { - outFile << "--input_direction " <wind->windTable->dir[i]->value()) <<"\n"; } - + if (writeCF) { + outFile << "--input_direction " << std::to_string(tree->wind->windTable->dir[i]->value()) << "\n"; + } army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); army->setInputWindHeight ( i, inHeight, inHeightUnits ); @@ -2997,17 +2910,11 @@ if (writeCF) { army->setOutputPath( i, outputDir.c_str() ); //diurnal, if needed - army->setDiurnalWinds( i, useDiurnal ); - - - - - - if( useDiurnal == true ) + army->setDiurnalWinds( i, useDiurnal ); + if( useDiurnal == true ) { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), @@ -3017,7 +2924,6 @@ if (writeCF) { army->setUniAirTemp( i, tree->wind->windTable->airTemp[i]->value(), tempUnits ); - army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -3042,7 +2948,6 @@ if (writeCF) { { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - army->setDateTime( i, tree->wind->windTable->date[i]->date().year(), tree->wind->windTable->date[i]->date().month(), tree->wind->windTable->date[i]->date().day(), @@ -3052,8 +2957,6 @@ if (writeCF) { army->setUniAirTemp( i, tree->wind->windTable->airTemp[i]->value(), tempUnits ); - - army->setUniCloudCover( i, tree->wind->windTable->cloudCover[i]->value(), coverUnits::percent ); @@ -3073,24 +2976,26 @@ if (writeCF) { else { #ifdef NINJAFOAM - if(useNinjaFoam){ - - if (writeCF) { - if(ninjafoamMeshChoice == WindNinjaInputs::coarse){ - outFile << "--mesh_count 25000\n"; - } - else if(meshChoice == WindNinjaInputs::medium){ - outFile << "--mesh_count 50000\n"; + if(useNinjaFoam) + { + army->setMeshCount( i, ninjafoamMeshChoice ); + if (writeCF) + { + if(ninjafoamMeshChoice == WindNinjaInputs::coarse) + { + outFile << "--mesh_count 25000\n"; + } else if(meshChoice == WindNinjaInputs::medium) + { + outFile << "--mesh_count 50000\n"; + } else if(meshChoice == WindNinjaInputs::fine) + { + outFile << "--mesh_count 100000\n"; + } } - else if(meshChoice == WindNinjaInputs::fine){ - outFile << "--mesh_count 100000\n"; - } - } - - army->setMeshCount( i, ninjafoamMeshChoice ); - if (writeCF) { - outFile << "--number_of_iterations 300\n";} army->setNumberOfIterations( i, 300); + if (writeCF) { + outFile << "--number_of_iterations 300\n"; + } } else army->setMeshResolutionChoice( i, meshChoice ); @@ -3138,32 +3043,31 @@ if (writeCF) { //army.setOutputFilenames(); army->setNinjaComNumRuns( i, nRuns ); - //add different input to config - domainRUNS.close(); - - std::string domainaveragepath = "DomainAverage/run " + std::to_string(i) + ".cfg"; - std::string domainaveragedeletion = "domainrun" + std::to_string(i) + ".cfg"; - std::cout << domainaveragepath << std::endl; - std::cout << domainaveragedeletion << std::endl; - if (writeCF) { - if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { - casefile.addFileToZip(zipFilePath, getdir, domainaveragepath, domaininputpath ); - } + //add different input to config + domainRUNS.close(); + std::string domainaveragepath = "DomainAverage/run" + std::to_string(i) + ".cfg"; + std::string domainaveragedeletion = "domainrun" + std::to_string(i) + ".cfg"; + if (writeCF) + { + if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) + { + casefile.addFileToZip(zipFilePath, getdir, domainaveragepath, domaininputpath ); + } } - casefile.deleteFileFromPath(getdir, domainaveragedeletion ); + casefile.deleteFileFromPath(getdir, domainaveragedeletion ); - } + } // for(int i = 0;i < army->getSize(); i++) //set Casefile Directory and Input - - if (writeCF) { - outFile.close(); - casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - + if (writeCF) + { + outFile.close(); + casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); + casefile.deleteFileFromPath(getdir, "selectedstations.csv"); } - army->set_writeFarsiteAtmFile( writeAtm && writeFb ); for( unsigned int i = 0; i < army->getSize(); i++ ) @@ -4228,6 +4132,21 @@ QString mainWindow::checkForNoData( QString inputFile ) return newFile; } +// string splitter, splits an input string into pieces separated by an input delimiter +// used for point initialization in casefile +std::vector mainWindow::split(const std::string &s, const std::string &delimiter) { + std::vector tokens; + size_t start = 0; + size_t end = s.find(delimiter); + while (end != std::string::npos) { + tokens.push_back(s.substr(start, end - start)); + start = end + delimiter.length(); + end = s.find(delimiter, start); + } + tokens.push_back(s.substr(start, end)); + return tokens; +} + void mainWindow::enablePointDate(bool enable) { (void)enable; diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index f398bd59..827edc94 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -47,9 +47,6 @@ #include #include #include -#include -#include - #include "gdal_priv.h" #include "ogr_srs_api.h" @@ -67,7 +64,9 @@ #include "ninjaUnits.h" #include "ninjaArmy.h" #include "ninja_conv.h" -#include "cpl_conv.h" // For CPLSetConfigOption + +#include +#include #include "setconfigdialog.h" @@ -90,7 +89,7 @@ class mainWindow : public QMainWindow QTimer *timer; - int *runProgress; + int *runProgress; int totalProgress; std::vector progressLog; @@ -196,7 +195,6 @@ class mainWindow : public QMainWindow void openOutputPath(); -std::vector split(const std::string &s, const std::string &delimiter) ; //functions for checking inputItems int checkInputItem(); int checkSurfaceItem(); @@ -293,6 +291,8 @@ std::vector split(const std::string &s, const std::string &delimite void writeSettings(); QString checkForNoData( QString fileName ); + std::vector split(const std::string &s, const std::string &delimiter); + QVBoxLayout *mainLayout; QFileSystemWatcher fileWatcher; diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index af2e542a..bb3df57e 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -3,7 +3,7 @@ std::string CaseFile::zipfilename = ""; std::string CaseFile::directory = ""; bool CaseFile::zipalreadyopened = false; -std::mutex zipMutex; +//std::mutex zipMutex; std::vector CaseFile::timesforWX; std::vector CaseFile::boundingboxarr; bool CaseFile::downloadedfromdem; @@ -82,8 +82,8 @@ std::string CaseFile::parse(const std::string& type, const std::string& path) { void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath) { // CPL logging enabled here - std::lock_guard lock(zipMutex); // for multithreading issue - CPLSetConfigOption("CPL_DEBUG", "ON"); + //std::lock_guard lock(zipMutex); // for multithreading issue + //CPLSetConfigOption("CPL_DEBUG", "ON"); try { bool foundzip = lookforzip(zipFilePath, dirPath); @@ -180,17 +180,20 @@ std::string CaseFile::getTime() { return oss.str(); } +// to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name void CaseFile::rename(std::string newname) { - std::string directory = getdir(); - std::string oldFilePath = zipfilename; - std::string newFilePath = newname ; + if (parse("file", zipfilename) == "tmp.ninja") + { + std::string oldFilePath = zipfilename; + std::string newFilePath = newname; - if (VSIRename(oldFilePath.c_str(), newFilePath.c_str()) == 0) { - CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", oldFilePath.c_str(), newFilePath.c_str()); - zipfilename = newname; - } else { - CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", oldFilePath.c_str(), newFilePath.c_str()); + if (VSIRename(oldFilePath.c_str(), newFilePath.c_str()) == 0) { + CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", oldFilePath.c_str(), newFilePath.c_str()); + zipfilename = newname; + } else { + CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", oldFilePath.c_str(), newFilePath.c_str()); + } } } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 4ef4d345..106a3d6c 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -40,7 +40,7 @@ #include #include #include -#include +//#include #include class CaseFile { @@ -94,4 +94,4 @@ class CaseFile { bool getDownloadedFromDEM () ; std::vector CaseFile::getBoundingBox (); -}; \ No newline at end of file +}; diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index b831241f..a63897a4 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -96,7 +96,7 @@ pair at_option_parser(string const&s) // if we have an 'elevation_file' program option check if file exists and has a non-geographic srs. // if the srs is geographic, try to convert to a UTM file in the configured 'output_path' (or current dir if not set) // return address of a string that points to a valid non-geographic file or NULL if none was found or could be constructed -const std::string* get_checked_elevation_file (po::variables_map& vm) +const std::string* get_checked_elevation_file(po::variables_map& vm) { if (vm.count("elevation_file")) { const string* filename = &vm["elevation_file"].as(); @@ -136,9 +136,8 @@ const std::string* get_checked_elevation_file (po::variables_map& vm) } } - -//split for point initialization in casefile - +// string splitter, splits an input string into pieces separated by an input delimiter +// used for point initialization in casefile std::vector split(const std::string &s, const std::string &delimiter) { std::vector tokens; size_t start = 0; @@ -152,7 +151,6 @@ std::vector split(const std::string &s, const std::string &delimite return tokens; } - /** * Command line implementation (CLI) of WindNinja. Can be run using command line args or * from an input file. @@ -183,7 +181,6 @@ int windNinjaCLI(int argc, char* argv[]) // Moved to initializeOptions() try { - // Declare a group of options that will be // allowed only on command line po::options_description generic("Generic options"); @@ -392,10 +389,9 @@ int windNinjaCLI(int argc, char* argv[]) po::parsed_options opts_command = po::command_line_parser(argc, argv). options(cmdline_options).extra_parser(at_option_parser).positional(p).run(); - + //write out parsed options for debugging if(writeParsed) { - typedef std::vector< po::basic_option > vec_opt; cout << "\n\nParsed command line options:" << endl; for(vec_opt::iterator l_itrOpt = opts_command.options.begin(); @@ -415,7 +411,6 @@ int windNinjaCLI(int argc, char* argv[]) } } - store(opts_command, vm); //notify(vm); if( argc == 1 ) @@ -456,27 +451,29 @@ int windNinjaCLI(int argc, char* argv[]) cout << endl; } } - store(opts_config, vm); //store(parse_config_file(ifs, config_file_options), vm); //notify(vm); } } + //helper for casefile output of CLI + if (vm["write_casefile"].as() == true) + { + CaseFile casefile; - if (vm["write_casefile"].as() == true) { - CaseFile casefile; std::string getdir = casefile.parse( "directory", vm["elevation_file"].as()); - std::string inputpath = getdir + "/config.cfg"; - + std::ofstream outFile(inputpath); - if (!outFile) { + if (!outFile) + { cerr << "Error: Could not open the file for writing!" << endl; return; } - - for (const auto& pair : vm) { + + for (const auto& pair : vm) + { const std::string& option_name = pair.first; const po::variable_value& option_value = pair.second; @@ -505,41 +502,45 @@ int windNinjaCLI(int argc, char* argv[]) } } - // This flush is actually optional because close() will flush automatically - std::string getfileName = casefile.parse("file", vm["elevation_file"].as()); std::string getconfigname = casefile.parse("file", vm["config_file"].as()); - std::string zipFilePath = getdir + "/" + getfileName + "-" + casefile.getTime() + ".ninja"; - casefile.setZipOpen(true); - casefile.setdir(getdir); - casefile.setzip(zipFilePath); + std::string zipFilePath = getdir + "/tmp.ninja"; + + casefile.setZipOpen(true); + casefile.setdir(getdir); + casefile.setzip(zipFilePath); + + // This flush is actually optional because close() will flush automatically outFile.flush(); outFile.close(); + casefile.addFileToZip(zipFilePath, getdir, getconfigname, vm["config_file"].as()); - casefile.addFileToZip(zipFilePath, getdir, getfileName, vm["elevation_file"].as()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); - if (vm.count("forecast_filename")) { + casefile.addFileToZip(zipFilePath, getdir, getfileName, vm["elevation_file"].as()); + casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); + casefile.deleteFileFromPath(getdir, "config.cfg"); + if (vm.count("forecast_filename")) + { std::string getweatherFileName = "weatherfile/" + casefile.parse("file", vm["forecast_filename"].as()); - casefile.addFileToZip(zipFilePath, getdir, getweatherFileName, vm["forecast_filename"].as()); + casefile.addFileToZip(zipFilePath, getdir, getweatherFileName, vm["forecast_filename"].as()); } - if (vm.count("wx_station_filename")) { - std::vector tokens = split(vm["wx_station_filename"].as(), "/"); - std::string getpointFileName = casefile.parse("file", vm["wx_station_filename"].as()); + if (vm.count("wx_station_filename")) + { + std::vector tokens = split(vm["wx_station_filename"].as(), "/"); + std::string getpointFileName = casefile.parse("file", vm["wx_station_filename"].as()); - if (tokens.size() >= 2) { - std::string secondToLastToken = tokens[tokens.size()-2]; - if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - getpointFileName = secondToLastToken + "/" + tokens[tokens.size() - 1]; - } - + if (tokens.size() >= 2) { + std::string secondToLastToken = tokens[tokens.size()-2]; + if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { + getpointFileName = secondToLastToken + "/" + tokens[tokens.size() - 1]; } - - casefile.addFileToZip(zipFilePath, getdir, getpointFileName, vm["wx_station_filename"].as()); + } + + casefile.addFileToZip(zipFilePath, getdir, getpointFileName, vm["wx_station_filename"].as()); } - } + } + if (vm.count("help")) { cout << visible << "\n"; return 0; @@ -806,7 +807,6 @@ int windNinjaCLI(int argc, char* argv[]) elevation_file = new string(new_elev); } - #endif //EMISSIONS if(vm.count("north") || vm.count("south") || @@ -1159,9 +1159,8 @@ int windNinjaCLI(int argc, char* argv[]) { //Check to be sure that the user specifies right info conflicting_options(vm, "fetch_station", "wx_station_filename"); - + std::vector timeList; - if(vm["fetch_station"].as() == true) //download station and make appropriate size ninjaArmy { const char *api_key_conf_opt = CPLGetConfigOption("CUSTOM_API_KEY","FALSE"); @@ -1225,7 +1224,6 @@ int windNinjaCLI(int argc, char* argv[]) vm["fetch_current_station_data"].as()); // stationPathName="blank"; pointInitialization::SetRawStationFilename(stationPathName); //Set this for fetching - std::cout << stationPathName << std::endl; //so that the fetchStationData function knows where to save the data option_dependency(vm,"fetch_station","fetch_type"); if (vm["fetch_type"].as()=="bbox") //Get data from Bounding Box @@ -1246,11 +1244,10 @@ int windNinjaCLI(int argc, char* argv[]) else if (vm["fetch_type"].as()=="stid") { option_dependency(vm,"fetch_type","fetch_station_name"); - + bool fetchSuccess = pointInitialization::fetchStationByName(vm["fetch_station_name"].as(), timeList, osTimeZone, vm["fetch_current_station_data"].as()); - if(fetchSuccess==false) //Fail to download data { pointInitialization::removeBadDirectory(stationPathName); //delete the generated dir @@ -1260,7 +1257,6 @@ int windNinjaCLI(int argc, char* argv[]) pointInitialization::writeStationLocationFile(stationPathName,*elevation_file,vm["fetch_current_station_data"].as()); } - else //If something else bad happens { pointInitialization::removeBadDirectory(stationPathName); //Get rid of generated dir @@ -1960,7 +1956,8 @@ int windNinjaCLI(int argc, char* argv[]) windsim.setPDFLineWidth( i_, vm["pdf_linewidth"].as() ); std::string pbm = vm["pdf_basemap"].as(); int pbs = 0; - if( pbm == "" ) + //if( pbm == "" ) + if( pbm == "hillshade" ) { pbs = 0; } diff --git a/src/ninja/cli.h b/src/ninja/cli.h index a6a2dea3..b69a2495 100644 --- a/src/ninja/cli.h +++ b/src/ninja/cli.h @@ -48,7 +48,7 @@ namespace po = boost::program_options; #include #include -#include +//#include //#include @@ -60,7 +60,13 @@ void option_dependency(const po::variables_map& vm, const char* for_what, const void verify_option_set(const po::variables_map& vm, const char* optn); -std::vector split(const std::string &s, const std::string &delimiter); +//bool checkArgs(string arg1, string arg2, string arg3); + +pair at_option_parser(string const&s); + +const std::string* get_checked_elevation_file(po::variables_map& vm); + +std::vector split(const std::string &s, const std::string &delimiter); // this should be used instead of direct 'variables_map["key"].as()' calls since otherwise a single typo // in the key literal results in undefined behavior that can corrupt memory miles away. @@ -75,6 +81,4 @@ inline T option_val (const po::variables_map& vm, const char* key) { } } -//bool checkArgs(string arg1, string arg2, string arg3); - #endif /* CLI_H */ diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 6ca6a764..a95604c5 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -154,7 +154,6 @@ ninja::ninja(const ninja &rhs) endSolve=0.0; startWriteOut=0.0; endWriteOut=0.0; - casefilename = ""; //Pointers to dynamically allocated memory DIAG=NULL; PHI=NULL; @@ -170,6 +169,8 @@ ninja::ninja(const ninja &rhs) slope=NULL; shade=NULL; solar=NULL; + + casefilename = rhs.casefilename; } /** @@ -246,6 +247,8 @@ ninja &ninja::operator=(const ninja &rhs) slope=NULL; shade=NULL; solar=NULL; + + casefilename = rhs.casefilename; } return *this; } @@ -2795,21 +2798,6 @@ void ninja::setUvGrids (AsciiGrid& angGrid, AsciiGrid& velGrid, } } - - - -std::string ninja::converttimetostd(const boost::local_time::local_date_time& ninjaTime) { - std::ostringstream ss; - - ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); - - ss << ninjaTime; - - std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); - return result; -} - - /**Writes output files. * Writes VTK, FARSITE ASCII Raster, text comparison, shape, and kmz output files. */ @@ -2817,55 +2805,11 @@ std::string ninja::converttimetostd(const boost::local_time::local_date_time& ni void ninja::writeOutputFiles() { set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); - - - // write to casefile regardless of if VTK is checked - bool VTKforcasefile = false; - CaseFile casefile; - if (casefile.getZipOpen()) { - casefile.rename(casefilename); - VTKforcasefile = true; - bool vtk_out_as_utm = false; - if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) - { - vtk_out_as_utm = CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"); - } - // can pick between "ascii" and "binary" format for the vtk write format - std::string vtkWriteFormat = "binary";//"binary";//"ascii"; - volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", input.volVTKFile); - std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); - std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); - - std::string timestr = ""; - std:: string getlocaltime = casefile.getTime(); - - //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; - if (input.ninjaTime.is_not_a_date_time()) { - timestr = getlocaltime; - } - else { - - timestr = converttimetostd(input.ninjaTime); - - } - - std::string getfileName = casefile.parse("file", input.dem.fileName); - - std::string zipFilePath = casefile.getzip(); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); - casefile.deleteFileFromPath(directoryPath , normfile); - casefile.deleteFileFromPath(directoryPath , surfFile); - - } + CaseFile casefile; //Write volume data to VTK format (always in m/s?) - - if(input.volVTKOutFlag && !VTKforcasefile) + //write to casefile regardless of if VTK is checked + if(input.volVTKOutFlag == true || casefile.getZipOpen()) { try{ bool vtk_out_as_utm = false; @@ -2877,8 +2821,38 @@ void ninja::writeOutputFiles() std::string vtkWriteFormat = "binary";//"binary";//"ascii"; volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - } - catch (exception& e) + std::string directoryPath = get_outputPath(); + std::string normfile = casefile.parse("file", input.volVTKFile); + std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); + std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); + if( casefile.getZipOpen() ) + { + casefile.rename(casefilename); + + std::string timestr = ""; + if( input.ninjaTime.is_not_a_date_time() ) + { + std::string getlocaltime = casefile.getTime(); + timestr = getlocaltime; + } else + { + timestr = converttimetostd(input.ninjaTime); + } + + std::string zipFilePath = casefile.getzip(); + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + } + + if( input.volVTKOutFlag == false ) + { + //casefile.deleteFileFromPath(directoryPath, normfile); + //casefile.deleteFileFromPath(directoryPath, surfFile); + casefile.deleteFileFromPath(directoryofVTK, normfile); + casefile.deleteFileFromPath(directoryofVTK, surfFile); + } + + }catch (exception& e) { input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); }catch (...) @@ -5331,6 +5305,14 @@ void ninja::dumpMemory() input.surface.deallocate(); } +std::string ninja::converttimetostd(const boost::local_time::local_date_time& ninjaTime) { + std::ostringstream ss; + ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); + ss << ninjaTime; + std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); + return result; +} + // derive a new pathname from the given one, swapping the path (if given) and optionally applying a regex replacement std::string derived_pathname (const char* pathname, const char* newpath, const char* pattern, const char* replacement) diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index fd7dd30e..a1ed365c 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -364,7 +364,9 @@ class ninja void checkInputs(); void dumpMemory(); - WindNinjaInputs input; //The place were all inputs (except mesh) are stored. + std::string converttimetostd(const boost::local_time::local_date_time& ninjaTime); + + WindNinjaInputs input; //The place where all inputs (except mesh) are stored. protected: void checkCancel(); @@ -483,7 +485,6 @@ class ninja void computeUVWField(); void prepareOutput(); bool matched(int iter); - std::string converttimetostd(const boost::local_time::local_date_time& ninjaTime) ; void writeOutputFiles(); void deleteDynamicMemory(); diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 242f2e7d..f148a3c3 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -34,7 +34,7 @@ const char* NinjaFoam::pszFoamPath = NULL; NinjaFoam::NinjaFoam() : ninja() { foamVersion = ""; - + pszVrtMem = NULL; pszGridFilename = NULL; pszTurbulenceGridFilename = NULL; @@ -73,8 +73,6 @@ NinjaFoam::NinjaFoam() : ninja() startStlConversion = 0.0; endStlConversion = 0.0; - casefilename = ""; - writeMassMeshVtk = false; } @@ -2665,31 +2663,12 @@ void NinjaFoam::WriteOutputFiles() } - - -const std::string NinjaFoam::get_outputPath() const -{ - return input.outputPath; -} - -std::string NinjaFoam::converttimetostdfoam(const boost::local_time::local_date_time& ninjaTime) { - std::ostringstream ss; - - ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); - - ss << ninjaTime; - - std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); - return result; -} - - - void NinjaFoam::writeMassMeshVtkOutput() { massMesh.buildStandardMesh(input); + // no longer need to resize any of the ascii grids, even L and bl_height, as they are already at the mass mesh resolution // after the dem is resampled to the mesh resolution they are set using the dem resolution, // and the mesh resolution now is expected to always match the mass solver mesh resolution @@ -2720,39 +2699,38 @@ void NinjaFoam::writeMassMeshVtkOutput() } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; - volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); + CaseFile casefile; - - if (casefile.getZipOpen()) { + std::string directoryPath = get_outputPath(); + std::string normfile = casefile.parse("file", massMeshVtkFilename); + std::string directoryofVTK = casefile.parse("directory", massMeshVtkFilename); + std::string surfFile = casefile.parse("file", massMeshVtkFilename).substr(0, casefile.parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile.parse("file", massMeshVtkFilename).substr(casefile.parse("file", massMeshVtkFilename).length() - 4, casefile.parse("file", massMeshVtkFilename).length()); + if( casefile.getZipOpen() ) + { casefile.rename(casefilename); - std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", massMeshVtkFilename); - std::string directoryofVTK = casefile.parse("directory", massMeshVtkFilename); - std::string surfFile = casefile.parse("file", massMeshVtkFilename).substr(0, casefile.parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile.parse("file", massMeshVtkFilename).substr(casefile.parse("file", massMeshVtkFilename).length() - 4, casefile.parse("file", massMeshVtkFilename).length()); - - std::string timestr = ""; - std:: string getlocaltime = casefile.getTime(); - //std::cout << input.ninjaTime.is_not_a_date_time() << std::endl; - if (input.ninjaTime.is_not_a_date_time()) { - timestr = getlocaltime; + std::string timestr = ""; + if( input.ninjaTime.is_not_a_date_time() ) + { + std::string getlocaltime = casefile.getTime(); + timestr = getlocaltime; + } else + { + timestr = converttimetostd(input.ninjaTime); } - else { - - timestr = converttimetostdfoam(input.ninjaTime); - } - - std::string getfileName = casefile.parse("file", input.dem.fileName); + std::string zipFilePath = casefile.getzip(); + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, massMeshVtkFilename); + casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + } - std::string zipFilePath = casefile.getzip(); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, massMeshVtkFilename); - - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); - casefile.deleteFileFromPath(directoryPath , normfile); - casefile.deleteFileFromPath(directoryPath , surfFile); + if( writeMassMeshVtk == false ) + { + ////casefile.deleteFileFromPath(directoryPath, normfile); + ////casefile.deleteFileFromPath(directoryPath, surfFile); + casefile.deleteFileFromPath(directoryofVTK, normfile); + casefile.deleteFileFromPath(directoryofVTK, surfFile); } } catch (exception& e) { diff --git a/src/ninja/ninjafoam.h b/src/ninja/ninjafoam.h index ab0d990a..2aba8b1d 100644 --- a/src/ninja/ninjafoam.h +++ b/src/ninja/ninjafoam.h @@ -59,9 +59,6 @@ " " \ "" - -extern std::string casefilenamefoam; - /** * \brief Main interface to OpenFOAM solver runs. * @@ -83,9 +80,6 @@ class NinjaFoam : public ninja virtual double get_meshResolution(); static int GenerateFoamDirectory(std::string demName); static void SetFoamPath(const char *pszPath); - const std::string get_outputPath() const; - std::string converttimetostdfoam(const boost::local_time::local_date_time& ninjaTime) ; - AsciiGrid TurbulenceGrid; private: @@ -109,7 +103,7 @@ class NinjaFoam : public ninja void ComputeDirection(); //converts direction from degrees to unit vector notation void SetInlets(); void SetBcs(); - + std::vector direction; //input.inputDirection converted to unit vector notation std::vector inlets; // e.g., north_face std::vector bcs; From 50efa79ebb1ebdc92e8b53afd88ddd52c31306fc Mon Sep 17 00:00:00 2001 From: latwood Date: Tue, 18 Mar 2025 18:30:24 -0600 Subject: [PATCH 17/35] 1st cleanup attempt of casefile stuff continued, for issue #7 cleaned up last gui stuff including making WidgetDownloadDEM.cpp drop the casefile data structure declaration to make it follow in the behavior and style of stationFetchWidget.cpp, other whitespace and naming cleanup, slight alterations to the function ordering cleanup of casefile.h and casefile.cpp was mostly just whitespace and parenthesis syntax, though I also attempted to make some of the global static vars that were no longer needed globally, defined in a standard constructor way. Still could use cleanup in casefile.h/.cpp some tab to space corrections in ninja.cpp and ninjafoam.cpp --- src/gui/WidgetDownloadDEM.cpp | 51 ++++-- src/gui/WidgetDownloadDEM.h | 12 +- src/gui/mainWindow.cpp | 35 ++-- src/gui/pointInput.cpp | 32 ++-- src/gui/pointInput.h | 4 +- src/gui/solvePage.cpp | 11 +- src/gui/solvePage.h | 4 +- src/gui/stationFetchWidget.cpp | 77 ++++----- src/gui/stationFetchWidget.h | 18 +-- src/ninja/casefile.cpp | 281 +++++++++++++++++++-------------- src/ninja/casefile.h | 65 ++++---- src/ninja/cli.cpp | 6 +- src/ninja/cli.h | 1 - src/ninja/ninja.cpp | 37 +++-- src/ninja/ninja.h | 1 - src/ninja/ninjafoam.cpp | 47 +++--- 16 files changed, 377 insertions(+), 305 deletions(-) diff --git a/src/gui/WidgetDownloadDEM.cpp b/src/gui/WidgetDownloadDEM.cpp index f205cf20..a28b2256 100644 --- a/src/gui/WidgetDownloadDEM.cpp +++ b/src/gui/WidgetDownloadDEM.cpp @@ -28,19 +28,21 @@ *****************************************************************************/ #include "WidgetDownloadDEM.h" -#include "casefile.h" //#include WidgetDownloadDEM::WidgetDownloadDEM(QWidget *parent) : QWidget(parent) { + wasDemFetched = false; + elevSource = ""; + demSelected = false; setupUi(this); setupGM(); initializeGoogleMapsInterface(); connectInputs(); - this->readSettings(); + this->readSettings(); // sets northBounds, southBound, eastBound, westBound initial values progressBar = new QProgressDialog(this); progressBar->setWindowModality(Qt::ApplicationModal); @@ -197,6 +199,8 @@ void WidgetDownloadDEM::setupGM() */ void WidgetDownloadDEM::saveDEM() { + wasDemFetched = true; + QVariant mbr = wvGoogleMaps->page()->mainFrame()->evaluateJavaScript("mbr()"); if(mbr.isNull()) { qDebug()<<"no mbr"; @@ -222,13 +226,6 @@ void WidgetDownloadDEM::saveDEM() westBound = mbrl[0].toDouble(); demSelected = true; - std::vector boundsarr = {northBound, southBound, eastBound, westBound}; - - CaseFile casefile; - - casefile.setDownloadedFromDEM(true); - casefile.setBoundingBox(boundsarr); - QString fileName; double boundArray[] = {this->northBound, this->eastBound, this->southBound, this->westBound}; double *boundBox; @@ -365,7 +362,7 @@ void WidgetDownloadDEM::updateDEMSource(int index) { switch(index){ case 0: //SRTM - CaseFile::setElevSource("srtm"); + elevSource = "srtm"; fetcher = FetchFactory::GetSurfaceFetch(FetchFactory::SRTM, FindDataPath("/data")); northDEMBound = srtm_northBound; southDEMBound = srtm_southBound; @@ -375,7 +372,7 @@ void WidgetDownloadDEM::updateDEMSource(int index) break; #ifdef HAVE_GMTED case 1: //GMTED - CaseFile::setElevSource("gmted"); + elevSource = "gmted"; fetcher = FetchFactory::GetSurfaceFetch(FetchFactory::WORLD_GMTED, FindDataPath("/data")); northDEMBound = world_gmted_northBound; southDEMBound = world_gmted_southBound; @@ -386,7 +383,7 @@ void WidgetDownloadDEM::updateDEMSource(int index) #endif #ifdef WITH_LCP_CLIENT case 2: //LCP - CaseFile::setElevSource("lcp"); + elevSource = "lcp"; fetcher = FetchFactory::GetSurfaceFetch(FetchFactory::LCP, FindDataPath("/data")); northDEMBound = lcp_northBound; southDEMBound = lcp_southBound; @@ -563,6 +560,36 @@ void WidgetDownloadDEM::readSettings() longitude = 43.911944; } +bool WidgetDownloadDEM::get_wasDemFetched() +{ + return wasDemFetched; +} + +std::string WidgetDownloadDEM::get_elevSource() +{ + return elevSource; +} + +double WidgetDownloadDEM::get_northBound() +{ + return northBound; +} + +double WidgetDownloadDEM::get_southBound() +{ + return southBound; +} + +double WidgetDownloadDEM::get_eastBound() +{ + return eastBound; +} + +double WidgetDownloadDEM::get_westBound() +{ + return westBound; +} + /** * @brief Handles close events of GUI such as clicking X close icon * diff --git a/src/gui/WidgetDownloadDEM.h b/src/gui/WidgetDownloadDEM.h index b79106a4..8389a76f 100644 --- a/src/gui/WidgetDownloadDEM.h +++ b/src/gui/WidgetDownloadDEM.h @@ -66,7 +66,14 @@ class WidgetDownloadDEM : public QWidget, private Ui::WidgetDownloadDEM void writeSettings(); void readSettings(); int fetchBoundBox(double *boundsBox, const char *fileName, double resolution); - + + bool get_wasDemFetched(); + std::string get_elevSource(); + double get_northBound(); + double get_southBound(); + double get_eastBound(); + double get_westBound(); + protected: void closeEvent(QCloseEvent *event); @@ -88,6 +95,9 @@ class WidgetDownloadDEM : public QWidget, private Ui::WidgetDownloadDEM private: QDialog dlg; + bool wasDemFetched; + std::string elevSource; + double latitude; double longitude; double northBound; diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 74402d4e..27819c30 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -67,6 +67,8 @@ mainWindow::mainWindow(QWidget *parent) GDALCenterLat = GDALCenterLon = 0; hasGDALCenter = false; + demWidget = NULL; + tree = new WindNinjaTree; createConsole(); @@ -1655,7 +1657,7 @@ void mainWindow::openOutputPath() int mainWindow::solve() { - bool writeCF = tree->solve->CaseFIBOX->isChecked(); + bool writeCF = tree->solve->CaseFileBox->isChecked(); CaseFile casefile; @@ -1708,15 +1710,14 @@ int mainWindow::solve() std::string demFile = inputFileName.toStdString(); if (writeCF) { - if (casefile.getDownloadedFromDEM() == true) + if (demWidget != NULL && demWidget->get_wasDemFetched() == true) { - std::vector vec = casefile.getBoundingBox(); outFile << "--fetch_elevation true" << "\n"; - outFile << "--north " << vec[0] << "\n"; - outFile << "--south " << vec[1] << "\n"; - outFile << "--west " << vec[2] << "\n"; - outFile << "--east " << vec[3] << "\n"; - outFile << "--elevation_source " << casefile.getElevSource() << "\n"; + outFile << "--north " << demWidget->get_northBound() << "\n"; + outFile << "--south " << demWidget->get_southBound() << "\n"; + outFile << "--west " << demWidget->get_westBound() << "\n"; + outFile << "--east " << demWidget->get_eastBound() << "\n"; + outFile << "--elevation_source " << demWidget->get_elevSource() << "\n"; } else { outFile << "--fetch_elevation false" << "\n"; @@ -1915,8 +1916,6 @@ int mainWindow::solve() } } - // handle widget download DEM in widgetdownloadDEM.cpp - //speed units and air temp units velocityUnits::eVelocityUnits inputSpeedUnits; if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 0) @@ -2355,7 +2354,7 @@ int mainWindow::solve() if (writeCF) { - if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true) + if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) { outFile << "--fetch_station true\n"; outFile << "--fetch_type " << tree->point->xWidget->getType() << "\n"; @@ -2368,15 +2367,15 @@ int mainWindow::solve() { outFile << "--fetch_station_name " << tree->point->xWidget->getStationIDS() << "\n"; } - if (tree->point->xWidget->getTimeseries() == false) + if (tree->point->xWidget->get_isTimeSeries() == false) { - outFile << "--fetch_current_station_data false\n"; - outFile << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + outFile << "--fetch_current_station_data true\n"; } else { - outFile << "--fetch_current_station_data true\n"; + outFile << "--fetch_current_station_data false\n"; + outFile << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; } - } else // if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true) + } else // if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) { outFile << "--fetch_station false\n"; if (useTimeList) @@ -2397,7 +2396,7 @@ int mainWindow::solve() { outFile << "--fetch_current_station_data true\n"; } - } // if (tree->point->xWidget != NULL && tree->point->xWidget->getActuallyPressed() == true) + } // if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) if (writeStationKML) { @@ -2783,7 +2782,7 @@ int mainWindow::solve() //get times for casefile if no times are clicked by user if (writeCF && times.size() == 0) { - std::vector wxtimesfromcasefile = casefile.getWXTIME(); + std::vector wxtimesfromcasefile = casefile.getWXTIME(); // is this even used??? I do not see even one setTimeWX() instance in the code before this spot std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); diff --git a/src/gui/pointInput.cpp b/src/gui/pointInput.cpp index 3de81b80..2938a7e3 100644 --- a/src/gui/pointInput.cpp +++ b/src/gui/pointInput.cpp @@ -91,7 +91,7 @@ pointInput::pointInput( QWidget *parent ) : QWidget( parent ) sfModel = new QDirModel(this); //Creates the directory model sfModel->setReadOnly(true); //probably can be true, but i don't know sfModel->setSorting(QDir::Time); //Sort by time created - + treeView = new QTreeView(this); //Creates the box where the sfModel goes treeView->setVisible(true); treeView->setModel(sfModel); //Sets the model to the thing above @@ -272,39 +272,42 @@ pointInput::~pointInput() } - - - -void pointInput::collectAllIndexes(const QModelIndex &parent, std::vector &allIndexes) const { - for (int row = 0; row < sfModel->rowCount(parent); ++row) { +void pointInput::collectAllIndexes(const QModelIndex &parent, std::vector &allIndexes) const +{ + for (int row = 0; row < sfModel->rowCount(parent); row++) + { QModelIndex index = sfModel->index(row, 0, parent); allIndexes.push_back(index); - if (sfModel->isDir(index)) { + if (sfModel->isDir(index)) + { collectAllIndexes(index, allIndexes); // Recursively collect child indexes } } } -void pointInput::generateFullFileList() { +void pointInput::generateFullFileList() +{ std::vector allIndexes; std::vector fileList; // Collect all indexes starting from the root index - QModelIndex rootIndex = treeView->rootIndex(); + QModelIndex rootIndex = treeView->rootIndex(); collectAllIndexes(rootIndex, allIndexes); - for (const QModelIndex &index : allIndexes) { - if (!sfModel->isDir(index)) { // Check if it is a file + for (const QModelIndex &index : allIndexes) + { + // Check if it is a file + if (!sfModel->isDir(index)) + { QString filePath = sfModel->filePath(index); fileList.push_back(filePath.toStdString()); } } - fullFileList = fileList; + fullFileList = fileList; } - /** * @brief pointInput::readStationFiles * Reads the files on disk that the user selects @@ -1033,7 +1036,6 @@ void pointInput::setDiurnalParam(bool diurnalCheck) CPLDebug("STATION_FETCH","DIURNAL/STABILITY STATUS: %i",isDiurnalChecked); } - /** * *@brief pointInput::checkForModelData * Applies filters to the tree @@ -1052,4 +1054,4 @@ void pointInput::checkForModelData() sfModel->setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); //QDir::Dir specifies to add filters to directories treeView->setRootIndex(sfModel->index(wd.absolutePath())); treeView->resizeColumnToContents(0); -} \ No newline at end of file +} diff --git a/src/gui/pointInput.h b/src/gui/pointInput.h index 7d438110..760f2037 100644 --- a/src/gui/pointInput.h +++ b/src/gui/pointInput.h @@ -160,8 +160,8 @@ class pointInput : public QWidget void setOneStepTimeseries(); private slots: - - void generateFullFileList() ; + + void generateFullFileList(); void collectAllIndexes(const QModelIndex &parent, std::vector &allIndexes) const; void readStationFiles(const QItemSelection &x ,const QItemSelection &y); diff --git a/src/gui/solvePage.cpp b/src/gui/solvePage.cpp index 0fc9d60c..d03efc8a 100644 --- a/src/gui/solvePage.cpp +++ b/src/gui/solvePage.cpp @@ -76,9 +76,8 @@ solvePage::solvePage(QWidget *parent) : QWidget(parent) openOutputPathButton->setIcon( QIcon( ":folder.png" ) ); openOutputPathButton->setDisabled( true ); - CaseFIBOX = new QCheckBox(tr("Generate a Casefile for this run"), this); - CaseFIBOX->setChecked(true); - connect(CaseFIBOX, SIGNAL(toggled(bool)), this, SLOT(onCasefileCheckBoxToggled(bool))); + CaseFileBox = new QCheckBox(tr("Generate Casefile"), this); + CaseFileBox->setChecked(true); layout = new QVBoxLayout; layout->addWidget(availProcLabel); @@ -86,8 +85,8 @@ solvePage::solvePage(QWidget *parent) : QWidget(parent) pageLayout = new QHBoxLayout; pageLayout->addWidget(numProcLabel); pageLayout->addWidget(numProcSpinBox); - pageLayout->addWidget(CaseFIBOX); pageLayout->addWidget(solveToolButton); + pageLayout->addWidget(CaseFileBox); pageLayout->addStretch(); outputPathLayout = new QHBoxLayout; @@ -116,10 +115,6 @@ void solvePage::chooseOutputDir() { outputDirLineEdit->setText( dir ); } -void solvePage::onCasefileCheckBoxToggled(bool checked) { -} - - QString solvePage::outputDirectory() { return outputDirLineEdit->text(); } diff --git a/src/gui/solvePage.h b/src/gui/solvePage.h index 20425633..89e3dade 100644 --- a/src/gui/solvePage.h +++ b/src/gui/solvePage.h @@ -59,7 +59,8 @@ class solvePage : public QWidget QString availProcString; QLabel *availProcLabel; QSpinBox *numProcSpinBox; - QCheckBox *CaseFIBOX; + QCheckBox *CaseFileBox; + QLabel *outputDirLabel; QLineEdit *outputDirLineEdit; QToolButton *outputDirToolButton; @@ -78,7 +79,6 @@ public slots: private slots: void chooseOutputDir(); - void onCasefileCheckBoxToggled(bool checked); }; #endif /* SOLVEPAGE_H */ diff --git a/src/gui/stationFetchWidget.cpp b/src/gui/stationFetchWidget.cpp index 99fe1c19..8bf4486c 100644 --- a/src/gui/stationFetchWidget.cpp +++ b/src/gui/stationFetchWidget.cpp @@ -47,7 +47,9 @@ stationFetchWidget::stationFetchWidget(QWidget *parent) currentBox->setVisible(false); fetchMetaButton->setVisible(false); //Hide the metadata button from the gui - pressedexecute = false; + + wasStationFetched = false; + stationFetchProgress = new QProgressDialog(this); //Sets up a mediocre progress bar that kind of works stationFetchProgress->setWindowModality(Qt::ApplicationModal); stationFetchProgress->setAutoReset(false); //Displays how far along the download process is @@ -196,7 +198,7 @@ void stationFetchWidget::updateFetchProgress() */ void stationFetchWidget::executeFetchStation() { - setActuallyPressed(true); + set_wasStationFetched(true); stationFetchProgress->setLabelText("Downloading Station Data!"); stationFetchProgress->setRange(0,0); //make it bounce back and forth stationFetchProgress->setCancelButtonText("Cancel"); @@ -258,52 +260,55 @@ std::string stationFetchWidget::demButcher()//Cleans up the DEM for use in the d return demPath; } -bool stationFetchWidget::getActuallyPressed() { - return pressedexecute; -} -void stationFetchWidget::setActuallyPressed(bool pressed) { - pressedexecute = pressed; +void stationFetchWidget::set_wasStationFetched(bool stationFetched) +{ + wasStationFetched = stationFetched; } +bool stationFetchWidget::get_wasStationFetched() +{ + return wasStationFetched; +} -std::string stationFetchWidget::getStationIDS() { - return removeWhiteSpace(idLine->text().toStdString()); +std::string stationFetchWidget::getType() +{ + if (geoLoc->currentIndex() == 0) + { + return "bbox"; + } else + { + return "stid"; + } } -int stationFetchWidget::getBuffer() { - if (bufferSpin->text().toDouble() == 0) { - return 0; - } +double stationFetchWidget::getBuffer() +{ return bufferSpin->text().toDouble(); } - - -std::string stationFetchWidget::getBufferUnits() { +std::string stationFetchWidget::getBufferUnits() +{ return buffUnits->currentText().toStdString(); } - -bool stationFetchWidget::getTimeseries() { - if (timeLoc->currentIndex() == 1) { - return false; - } - else { - return true; - } +std::string stationFetchWidget::getStationIDS() +{ + return removeWhiteSpace(idLine->text().toStdString()); } -std::string stationFetchWidget::getType() { - if (geoLoc->currentIndex() == 0) { - return "bbox"; - } - else { - return "stid"; +bool stationFetchWidget::get_isTimeSeries() +{ + if (timeLoc->currentIndex() == 1) + { + // is a time series + return true; + } else + { + // is a single time + return false; } } - - /** * @brief stationFetchWidget::fetchStation * Fetches data from the Mesowest API based on GUI request @@ -326,7 +331,7 @@ int stationFetchWidget::fetchStation() std::string demUse=demButcher(); std::string stationPathName; CPLDebug("STATION_FETCH","USING DEM: %s",demUse.c_str()); - + int terrainPart=geoLoc->currentIndex(); int timePart=timeLoc->currentIndex(); @@ -389,14 +394,13 @@ int stationFetchWidget::fetchStation() bufferUnits=buffUnits->currentText().toStdString(); fetchNow=true; - //Set the Station Buffer - + //Set the Station Buffer pointInitialization::setStationBuffer(buffer,bufferUnits); //Generates the directory to store the file names, because current data is on, don't specify time zone stationPathName=pointInitialization::generatePointDirectory(demFileName.toStdString(),demUse,true); pointInitialization::SetRawStationFilename(stationPathName); - result = pointInitialization::fetchStationFromBbox(demFileName.toStdString(),eTimeList,tzString.toStdString(),fetchNow); + CPLDebug("STATION_FETCH","Return: %i",result); } //DEM and Time series @@ -469,6 +473,7 @@ int stationFetchWidget::fetchStation() int sY,sMo,sD,sH,sMi; int eY,eMo,eD,eH,eMi; int numSteps=10; //make up a number for now.... It really doesn't matter at this point + std::string StartTime=startEdit->text().toStdString(); std::string EndTime=endEdit->text().toStdString(); diff --git a/src/gui/stationFetchWidget.h b/src/gui/stationFetchWidget.h index 998c479e..f18af8aa 100644 --- a/src/gui/stationFetchWidget.h +++ b/src/gui/stationFetchWidget.h @@ -47,8 +47,6 @@ #include "ui_stationFetchWidget.h" #include "GoogleMapsInterface.h" -#include -#include #include "pointInitialization.h" #ifndef PI @@ -69,14 +67,14 @@ class stationFetchWidget : public QWidget, private Ui::stationFetchWidget QString tzString; void updatetz(QString tz); void fixTime(); - std::string removeWhiteSpace(std::string str); - void setActuallyPressed(bool pressed); - bool getActuallyPressed(); - std::string getStationIDS(); - int getBuffer(); + std::string removeWhiteSpace(std::string str); + void set_wasStationFetched(bool stationFetched); + bool get_wasStationFetched(); + std::string getType(); + double getBuffer(); std::string getBufferUnits(); - bool getTimeseries(); - std::string getType(); + std::string getStationIDS(); + bool get_isTimeSeries(); protected: void closeEvent(QCloseEvent *event); @@ -102,7 +100,7 @@ class stationFetchWidget : public QWidget, private Ui::stationFetchWidget //Progress Bar Stuff QProgressDialog *stationFetchProgress; QFutureWatcher stationFutureWatcher; - bool pressedexecute; + bool wasStationFetched; friend class pointInput; }; diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index bb3df57e..00c975ec 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -3,84 +3,95 @@ std::string CaseFile::zipfilename = ""; std::string CaseFile::directory = ""; bool CaseFile::zipalreadyopened = false; + //std::mutex zipMutex; -std::vector CaseFile::timesforWX; -std::vector CaseFile::boundingboxarr; -bool CaseFile::downloadedfromdem; -std::string CaseFile::elevsource; -CaseFile::CaseFile() { +CaseFile::CaseFile() +{ + downloadedfromdem = false; + elevsource = ""; } -bool CaseFile::isCfgFile(const std::string& filePath) { +bool CaseFile::isCfgFile(const std::string& filePath) +{ const std::string extension = ".cfg"; - if (filePath.length() >= extension.length()) { + if (filePath.length() >= extension.length()) + { std::string fileExtension = filePath.substr(filePath.length() - extension.length()); return fileExtension == extension; - } else { + } else + { return false; } } -bool CaseFile::isVTKFile(const std::string& filePath) { +bool CaseFile::isVTKFile(const std::string& filePath) +{ const std::string extension = ".vtk"; - if (filePath.length() >= extension.length()) { + if (filePath.length() >= extension.length()) + { std::string fileExtension = filePath.substr(filePath.length() - extension.length()); return fileExtension == extension; - } else { + } else + { return false; } } -bool CaseFile::lookforzip(const std::string& zipFilePath, const std::string& directory) { +bool CaseFile::lookforzip(const std::string& zipFilePath, const std::string& directory) +{ char** papszDir = VSIReadDir(directory.c_str()); - if (papszDir != nullptr) { - - for (int i = 0; papszDir[i] != nullptr; i++) { - std::string entry = papszDir[i]; + if (papszDir != nullptr) + { + for (int i = 0; papszDir[i] != nullptr; i++) + { + std::string entry = papszDir[i]; - if (entry == "." || entry == "..") { - continue; - } + if (entry == "." || entry == "..") + { + continue; + } - if (entry == parse("file", getzip())) { - return true; + if (entry == parse("file", getzip())) + { + return true; + } } - } - - CSLDestroy(papszDir); + CSLDestroy(papszDir); } return false; } -bool CaseFile::lookfordate(const std::string& date) { - return false; +bool CaseFile::lookfordate(const std::string& date) +{ + return false; } - - - -std::string CaseFile::parse(const std::string& type, const std::string& path) { - size_t found = path.find_last_of("/"); - if (found != std::string::npos) { - if (strcmp(type.c_str(), "directory") == 0) { - return path.substr(0, found); - - } - else - if (strcmp(type.c_str(), "file") == 0) { - return path.substr(found + 1); // Extract substring after the last '/' - } - } else +std::string CaseFile::parse(const std::string& type, const std::string& path) +{ + size_t found = path.find_last_of("/"); + if (found != std::string::npos) + { + if (strcmp(type.c_str(), "directory") == 0) + { + return path.substr(0, found); + } else + { + if (strcmp(type.c_str(), "file") == 0) { - //std::cout << "couldn't parse" << std::endl; - //return ""; - return path; + return path.substr(found + 1); // Extract substring after the last '/' } + } + } else + { + //std::cout << "couldn't parse" << std::endl; + //return ""; + return path; + } } - -void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath) { +void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath) +{ // CPL logging enabled here //std::lock_guard lock(zipMutex); // for multithreading issue //CPLSetConfigOption("CPL_DEBUG", "ON"); @@ -88,35 +99,42 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d try { bool foundzip = lookforzip(zipFilePath, dirPath); - if (foundzip) { + if (foundzip) + { std::ifstream infile(zipFilePath); - if (!infile.good()) { + if (!infile.good()) + { CPLDebug("ZIP", "ZIP file does not exist: %s", zipFilePath.c_str()); return; } } zipFile zip; - if (!foundzip) { + if (!foundzip) + { zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_CREATE); - } else { + } else + { zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_ADDINZIP); } - if (zip == NULL) { + if (zip == NULL) + { CPLDebug("ZIP", "Could not open ZIP: %s", zipFilePath.c_str()); return; } zip_fileinfo zi = {0}; - if (cpl_zipOpenNewFileInZip(zip, fileToAdd.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { + if (cpl_zipOpenNewFileInZip(zip, fileToAdd.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) + { CPLDebug("ZIP", "Could not open new file in ZIP: %s", fileToAdd.c_str()); cpl_zipClose(zip, nullptr); return; } VSILFILE *file = VSIFOpenL(usrlocalpath.c_str(), "rb"); - if (file == nullptr) { + if (file == nullptr) + { CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", usrlocalpath.c_str()); cpl_zipCloseFileInZip(zip); cpl_zipClose(zip, nullptr); @@ -128,7 +146,8 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d VSIFSeekL(file, 0, SEEK_SET); char *data = (char*)CPLMalloc(fileSize); - if (data == nullptr) { + if (data == nullptr) + { CPLDebug("Memory", "Failed to allocate memory for file data."); VSIFCloseL(file); cpl_zipCloseFileInZip(zip); @@ -136,7 +155,8 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d return; } - if (VSIFReadL(data, 1, fileSize, file) != fileSize) { + if (VSIFReadL(data, 1, fileSize, file) != fileSize) + { CPLDebug("FileRead", "Failed to read file contents: %s", fileToAdd.c_str()); CPLFree(data); VSIFCloseL(file); @@ -145,7 +165,8 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d return; } - if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) { + if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) + { CPLDebug("ZIP", "Error writing data to ZIP file: %s", fileToAdd.c_str()); } @@ -153,134 +174,150 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d VSIFCloseL(file); cpl_zipCloseFileInZip(zip); - if (cpl_zipClose(zip, nullptr) != ZIP_OK) { + if (cpl_zipClose(zip, nullptr) != ZIP_OK) + { CPLDebug("ZIP", "Error closing ZIP file: %s", zipFilePath.c_str()); } - } catch (const std::exception& e) { + } catch (const std::exception& e) + { CPLDebug("Exception", "Caught exception: %s", e.what()); CPLError(CE_Failure, CPLE_AppDefined, "Exception caught: %s", e.what()); - } catch (...) { + } catch (...) + { CPLDebug("Exception", "Caught unknown exception."); CPLError(CE_Failure, CPLE_AppDefined, "Caught unknown exception."); } } +std::string CaseFile::getTime() +{ + auto now = std::chrono::system_clock::now(); + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + std::tm* local_tm = std::localtime(&now_time_t); -std::string CaseFile::getTime() { - auto now = std::chrono::system_clock::now(); - - std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); - - std::tm* local_tm = std::localtime(&now_time_t); - - std::ostringstream oss; - oss << std::put_time(local_tm, "%Y-%m-%d %H:%M:%S"); - return oss.str(); + std::ostringstream oss; + oss << std::put_time(local_tm, "%Y-%m-%d %H:%M:%S"); + return oss.str(); } // to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name -void CaseFile::rename(std::string newname) { - +void CaseFile::rename(std::string newname) +{ if (parse("file", zipfilename) == "tmp.ninja") { std::string oldFilePath = zipfilename; std::string newFilePath = newname; - if (VSIRename(oldFilePath.c_str(), newFilePath.c_str()) == 0) { + if (VSIRename(oldFilePath.c_str(), newFilePath.c_str()) == 0) + { CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", oldFilePath.c_str(), newFilePath.c_str()); zipfilename = newname; - } else { + } else + { CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", oldFilePath.c_str(), newFilePath.c_str()); } } } - -void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filename) { - +void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filename) +{ char** papszDir = VSIReadDir(directoryPath.c_str()); - if (papszDir != nullptr) { - - for (int i = 0; papszDir[i] != nullptr; i++) { - std::string entry = papszDir[i]; + if (papszDir != nullptr) + { + for (int i = 0; papszDir[i] != nullptr; i++) + { + std::string entry = papszDir[i]; - if (entry == "." || entry == "..") { - continue; - } + if (entry == "." || entry == "..") + { + continue; + } - std::string fullPath = directoryPath + "/" + entry; + std::string fullPath = directoryPath + "/" + entry; - if (entry == filename) { - VSIUnlink(fullPath.c_str()); + if (entry == filename) + { + VSIUnlink(fullPath.c_str()); + } } - - } - - CSLDestroy(papszDir); + CSLDestroy(papszDir); } } - - -void CaseFile::setdir(std::string dir) { - directory = dir; +void CaseFile::setdir(std::string dir) +{ + directory = dir; } -std::string CaseFile::getzip() { +std::string CaseFile::getzip() +{ return zipfilename; } - -void CaseFile::setzip(std::string zip) { - zipfilename = zip; +void CaseFile::setzip(std::string zip) +{ + zipfilename = zip; } -std::string CaseFile::getdir() { +std::string CaseFile::getdir() +{ return directory; } -void CaseFile::setZipOpen(bool zipopen) { - if (zipopen) { - zipalreadyopened = true; - } - else { - zipalreadyopened = false; + +void CaseFile::setZipOpen(bool zipopen) +{ + if (zipopen) + { + zipalreadyopened = true; + } else + { + zipalreadyopened = false; } } -bool CaseFile::getZipOpen() { +bool CaseFile::getZipOpen() +{ return zipalreadyopened; } - -void CaseFile::setTimeWX (std::vector timeList ) { + +void CaseFile::setTimeWX(std::vector timeList) +{ timesforWX = timeList; } -std::vector CaseFile::getWXTIME () { +std::vector CaseFile::getWXTIME() +{ return timesforWX; } - -void CaseFile::setBoundingBox ( std::vector boundingboxarrr) { - boundingboxarr = boundingboxarrr; +void CaseFile::setBoundingBox(std::vector boundingboxarrr) +{ + boundingboxarr = boundingboxarrr; } -void CaseFile::setElevSource (std::string elevsourcee ) { - elevsource = elevsourcee; +void CaseFile::setElevSource(std::string elevsourcee) +{ + elevsource = elevsourcee; } -void CaseFile::setDownloadedFromDEM (bool downloadedfromdemm) { - downloadedfromdem = downloadedfromdemm; +void CaseFile::setDownloadedFromDEM(bool downloadedfromdemm) +{ + downloadedfromdem = downloadedfromdemm; } -std::string CaseFile::getElevSource () { - return elevsource; +std::string CaseFile::getElevSource() +{ + return elevsource; } -bool CaseFile::getDownloadedFromDEM () { - return downloadedfromdem; + +bool CaseFile::getDownloadedFromDEM() +{ + return downloadedfromdem; } -std::vector CaseFile::getBoundingBox () { - return boundingboxarr; +std::vector CaseFile::getBoundingBox() +{ + return boundingboxarr; } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 106a3d6c..1e6c4661 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -3,7 +3,7 @@ * $Id$ * * Project: WindNinja - * Purpose: Input/Output Handling of Casefile for VTK + * Purpose: Input/Output Handling of Casefile * Author: Rui Zhang * ****************************************************************************** @@ -34,7 +34,7 @@ #include "gdal.h" #include #include -#include +#include #include #include "cpl_minizip_zip.h" #include @@ -43,55 +43,56 @@ //#include #include -class CaseFile { +class CaseFile +{ private: static std::string zipfilename; static std::string directory; - static bool zipalreadyopened; + static bool zipalreadyopened; - static std::vector timesforWX; - static std::vector boundingboxarr; - static bool downloadedfromdem; - static std::string elevsource; + std::vector timesforWX; + std::vector boundingboxarr; + bool downloadedfromdem; + std::string elevsource; public: - CaseFile(); + CaseFile(); void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath); void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); - bool lookforzip(const std::string& zipFilePath, const std::string& directory); - bool isCfgFile(const std::string& filePath); - bool isVTKFile(const std::string& filePath); + bool lookforzip(const std::string& zipFilePath, const std::string& directory); + bool isCfgFile(const std::string& filePath); + bool isVTKFile(const std::string& filePath); - std::string parse(const std::string& type, const std::string& path) ; - std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); - bool lookfordate(const std::string& date) ; + std::string parse(const std::string& type, const std::string& path); + std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); + bool lookfordate(const std::string& date); - std::string getTime(); - void rename(std::string newname); - std::string getdir() ; - void setdir(std::string dir); + std::string getTime(); + void rename(std::string newname); + std::string getdir(); + void setdir(std::string dir); - std::string getzip () ; - void setzip(std::string zip); + std::string getzip(); + void setzip(std::string zip); - void setZipOpen(bool zipopen); - bool getZipOpen(); - void setTimeWX(std::vector timeList) ; - - std::vector getWXTIME() ; + void setZipOpen(bool zipopen); + bool getZipOpen(); + void setTimeWX(std::vector timeList); - void setBoundingBox ( std::vector boundingboxarrr); + std::vector getWXTIME(); - static void setElevSource (std::string elevsourcee ); + void setBoundingBox(std::vector boundingboxarrr); - void setDownloadedFromDEM (bool downloadedfromdemm) ; + void setElevSource(std::string elevsourcee); - std::string getElevSource () ; - bool getDownloadedFromDEM () ; + void setDownloadedFromDEM(bool downloadedfromdemm); - std::vector CaseFile::getBoundingBox (); + std::string getElevSource(); + bool getDownloadedFromDEM(); + + std::vector CaseFile::getBoundingBox(); }; diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index a63897a4..bf61a45a 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -180,7 +180,6 @@ int windNinjaCLI(int argc, char* argv[]) // Moved to initializeOptions() try { - // Declare a group of options that will be // allowed only on command line po::options_description generic("Generic options"); @@ -413,6 +412,7 @@ int windNinjaCLI(int argc, char* argv[]) store(opts_command, vm); //notify(vm); + if( argc == 1 ) { cout << visible << "\n"; @@ -451,6 +451,7 @@ int windNinjaCLI(int argc, char* argv[]) cout << endl; } } + store(opts_config, vm); //store(parse_config_file(ifs, config_file_options), vm); //notify(vm); @@ -1956,7 +1957,6 @@ int windNinjaCLI(int argc, char* argv[]) windsim.setPDFLineWidth( i_, vm["pdf_linewidth"].as() ); std::string pbm = vm["pdf_basemap"].as(); int pbs = 0; - //if( pbm == "" ) if( pbm == "hillshade" ) { pbs = 0; @@ -1967,7 +1967,7 @@ int windNinjaCLI(int argc, char* argv[]) } else { - cout << "Invalid pdf base map: " << pbm << ". Should be 'topofire' or 'hillshade'"; + cout << "Invalid pdf base map: " << pbm << ". Should be 'topofire' or 'hillshade'" << endl; } windsim.setPDFBaseMap( i_, pbs ); conflicting_options(vm, "pdf_size", "pdf_height"); diff --git a/src/ninja/cli.h b/src/ninja/cli.h index b69a2495..6efc4a86 100644 --- a/src/ninja/cli.h +++ b/src/ninja/cli.h @@ -48,7 +48,6 @@ namespace po = boost::program_options; #include #include -//#include //#include diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index a95604c5..eb53ad3b 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2801,25 +2801,24 @@ void ninja::setUvGrids (AsciiGrid& angGrid, AsciiGrid& velGrid, /**Writes output files. * Writes VTK, FARSITE ASCII Raster, text comparison, shape, and kmz output files. */ - void ninja::writeOutputFiles() { set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); CaseFile casefile; - //Write volume data to VTK format (always in m/s?) - //write to casefile regardless of if VTK is checked - if(input.volVTKOutFlag == true || casefile.getZipOpen()) - { - try{ + //Write volume data to VTK format (always in m/s?) + //write to casefile regardless of if VTK is checked + if(input.volVTKOutFlag == true || casefile.getZipOpen()) + { + try{ bool vtk_out_as_utm = false; - if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) + if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) { vtk_out_as_utm = CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"); } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "binary";//"binary";//"ascii"; - volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); + volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); std::string directoryPath = get_outputPath(); std::string normfile = casefile.parse("file", input.volVTKFile); @@ -2852,18 +2851,18 @@ void ninja::writeOutputFiles() casefile.deleteFileFromPath(directoryofVTK, surfFile); } - }catch (exception& e) - { - input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); - }catch (...) - { - input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: Cannot determine exception type."); - } - } + }catch (exception& e) + { + input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); + }catch (...) + { + input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: Cannot determine exception type."); + } + } - u.deallocate(); - v.deallocate(); - w.deallocate(); + u.deallocate(); + v.deallocate(); + w.deallocate(); #pragma omp parallel sections { diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index a1ed365c..fb5616be 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -485,7 +485,6 @@ class ninja void computeUVWField(); void prepareOutput(); bool matched(int iter); - void writeOutputFiles(); void deleteDynamicMemory(); diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index f148a3c3..3994c79b 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -72,7 +72,7 @@ NinjaFoam::NinjaFoam() : ninja() endOutputSampling = 0.0; startStlConversion = 0.0; endStlConversion = 0.0; - + writeMassMeshVtk = false; } @@ -2205,7 +2205,7 @@ void NinjaFoam::SetOutputFilenames() input.outputPath = pathName; timeAppend = timestream.str(); - + ostringstream wxModelTimestream; boost::local_time::local_time_facet* wxModelOutputFacet; @@ -2644,23 +2644,24 @@ void NinjaFoam::WriteOutputFiles() { input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during pdf file writing: Cannot determine exception type."); } - - - try{ + + + try{ CaseFile casefile; // write mass mesh if casefile is turned on - casefile always needs a vtk - if (writeMassMeshVtk == true || casefile.getZipOpen()) { + if (writeMassMeshVtk == true || casefile.getZipOpen()) + { CPLDebug("NINJAFOAM", "writing mass mesh vtk output for foam simulation."); writeMassMeshVtkOutput(); } - }catch (exception& e) - { - input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during NINJAFOAM mass mesh vtk file writing: %s", e.what()); - }catch (...) - { - input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during NINJAFOAM mass mesh vtk file writing: Cannot determine exception type."); - } - + }catch (exception& e) + { + input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during NINJAFOAM mass mesh vtk file writing: %s", e.what()); + }catch (...) + { + input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during NINJAFOAM mass mesh vtk file writing: Cannot determine exception type."); + } + } void NinjaFoam::writeMassMeshVtkOutput() @@ -2693,7 +2694,7 @@ void NinjaFoam::writeMassMeshVtkOutput() try { CPLDebug("NINJAFOAM", "writing vtk file"); bool vtk_out_as_utm = false; - if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) + if(CSLTestBoolean(CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"))) { vtk_out_as_utm = CPLGetConfigOption("VTK_OUT_AS_UTM", "FALSE"); } @@ -2733,15 +2734,15 @@ void NinjaFoam::writeMassMeshVtkOutput() casefile.deleteFileFromPath(directoryofVTK, surfFile); } - } catch (exception& e) { - input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); - } catch (...) { - input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: Cannot determine exception type."); - } + } catch (exception& e) { + input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: %s", e.what()); + } catch (...) { + input.Com->ninjaCom(ninjaComClass::ninjaWarning, "Exception caught during volume VTK file writing: Cannot determine exception type."); + } - u.deallocate(); - v.deallocate(); - w.deallocate(); + u.deallocate(); + v.deallocate(); + w.deallocate(); } void NinjaFoam::writeProbeSampleFile( const wn_3dArray& x, const wn_3dArray& y, const wn_3dArray& z, From 000922d67d532843bde255ce31a424ad7a42c09b Mon Sep 17 00:00:00 2001 From: latwood Date: Wed, 19 Mar 2025 14:20:11 -0600 Subject: [PATCH 18/35] adjusted casefile to no longer use global style variables, by setting up a pointer to the casefile in ninja/ninjafoam. Tested and it also works for diurnal. For issue #7 --- src/gui/mainWindow.cpp | 2 ++ src/ninja/casefile.cpp | 8 +++---- src/ninja/casefile.h | 12 +++++++--- src/ninja/cli.cpp | 7 +++--- src/ninja/ninja.cpp | 51 +++++++++++++++++++++++++++++------------ src/ninja/ninja.h | 4 +++- src/ninja/ninjaArmy.cpp | 7 ++++++ src/ninja/ninjaArmy.h | 11 +++++++++ src/ninja/ninjafoam.cpp | 33 ++++++++++++-------------- 9 files changed, 91 insertions(+), 44 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 27819c30..542cee07 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -2834,6 +2834,8 @@ int mainWindow::solve() for(int i = 0;i < army->getSize(); i++) { + army->setCaseFilePtr( i, casefile ); + std::string domaininputpath = getdir + "/domainrun" + std::to_string(i) + ".cfg"; std::ofstream domainRUNS(domaininputpath); // add runs to files diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 00c975ec..93d2f10f 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -1,13 +1,13 @@ #include "casefile.h" -std::string CaseFile::zipfilename = ""; -std::string CaseFile::directory = ""; -bool CaseFile::zipalreadyopened = false; - //std::mutex zipMutex; CaseFile::CaseFile() { + zipfilename = ""; + directory = ""; + zipalreadyopened = false; + downloadedfromdem = false; elevsource = ""; } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 1e6c4661..e73805e7 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -27,6 +27,9 @@ * *****************************************************************************/ +#ifndef CASEFILE_H +#define CASEFILE_H + #include #include #include @@ -47,10 +50,10 @@ class CaseFile { private: - static std::string zipfilename; - static std::string directory; - static bool zipalreadyopened; + bool zipalreadyopened; + std::string directory; + std::string zipfilename; std::vector timesforWX; std::vector boundingboxarr; @@ -96,3 +99,6 @@ class CaseFile std::vector CaseFile::getBoundingBox(); }; + +#endif /* CASEFILE_H */ + diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index bf61a45a..085f7e00 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -459,10 +459,9 @@ int windNinjaCLI(int argc, char* argv[]) } //helper for casefile output of CLI + CaseFile casefile; if (vm["write_casefile"].as() == true) { - CaseFile casefile; - std::string getdir = casefile.parse( "directory", vm["elevation_file"].as()); std::string inputpath = getdir + "/config.cfg"; @@ -1443,7 +1442,9 @@ int windNinjaCLI(int argc, char* argv[]) windsim.setDEM( i_, *elevation_file ); windsim.setPosition( i_ ); //get position from DEM file - + + windsim.setCaseFilePtr( i_, casefile ); + #ifdef NINJAFOAM if(vm["momentum_flag"].as()){ conflicting_options(vm, "mesh_choice", "mesh_count"); diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index eb53ad3b..5bdb3923 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -84,6 +84,7 @@ ninja::ninja() input.Com = new ninjaDefaultComHandler(); casefilename = ""; + casefile = NULL; } /**Ninja destructor @@ -171,6 +172,8 @@ ninja::ninja(const ninja &rhs) solar=NULL; casefilename = rhs.casefilename; + //casefile = NULL; // ONLY DO THIS IF WANTING THE MEMORY TO BE RESET TO A DEFAULT VALUE EVEN DURING COPY/OPERATOR=. Not wanted for this case, using this for diurnal sims loses the pointer + casefile = rhs.casefile; } /** @@ -249,6 +252,8 @@ ninja &ninja::operator=(const ninja &rhs) solar=NULL; casefilename = rhs.casefilename; + //casefile = NULL; // ONLY DO THIS IF WANTING THE MEMORY TO BE RESET TO A DEFAULT VALUE EVEN DURING COPY/OPERATOR=. Not wanted for this case, using this for diurnal sims loses the pointer + casefile = rhs.casefile; } return *this; } @@ -2805,10 +2810,9 @@ void ninja::writeOutputFiles() { set_outputFilenames(mesh.meshResolution, mesh.meshResolutionUnits); - CaseFile casefile; //Write volume data to VTK format (always in m/s?) //write to casefile regardless of if VTK is checked - if(input.volVTKOutFlag == true || casefile.getZipOpen()) + if(input.volVTKOutFlag == true || casefile->getZipOpen()) { try{ bool vtk_out_as_utm = false; @@ -2821,34 +2825,34 @@ void ninja::writeOutputFiles() volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", input.volVTKFile); - std::string directoryofVTK = casefile.parse("directory", input.volVTKFile); - std::string surfFile = casefile.parse("file", input.volVTKFile).substr(0, casefile.parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile.parse("file", input.volVTKFile).substr(casefile.parse("file", input.volVTKFile).length() - 4, casefile.parse("file", input.volVTKFile).length()); - if( casefile.getZipOpen() ) + std::string normfile = casefile->parse("file", input.volVTKFile); + std::string directoryofVTK = casefile->parse("directory", input.volVTKFile); + std::string surfFile = casefile->parse("file", input.volVTKFile).substr(0, casefile->parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile->parse("file", input.volVTKFile).substr(casefile->parse("file", input.volVTKFile).length() - 4, casefile->parse("file", input.volVTKFile).length()); + if( casefile->getZipOpen() ) { - casefile.rename(casefilename); + casefile->rename(casefilename); std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) { - std::string getlocaltime = casefile.getTime(); + std::string getlocaltime = casefile->getTime(); timestr = getlocaltime; } else { timestr = converttimetostd(input.ninjaTime); } - std::string zipFilePath = casefile.getzip(); - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + std::string zipFilePath = casefile->getzip(); + casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); + casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); } if( input.volVTKOutFlag == false ) { - //casefile.deleteFileFromPath(directoryPath, normfile); - //casefile.deleteFileFromPath(directoryPath, surfFile); - casefile.deleteFileFromPath(directoryofVTK, normfile); - casefile.deleteFileFromPath(directoryofVTK, surfFile); + //casefile->deleteFileFromPath(directoryPath, normfile); + //casefile->deleteFileFromPath(directoryPath, surfFile); + casefile->deleteFileFromPath(directoryofVTK, normfile); + casefile->deleteFileFromPath(directoryofVTK, surfFile); } }catch (exception& e) @@ -3307,6 +3311,13 @@ void ninja::deleteDynamicMemory() outputDirectionArray = NULL; } + if(casefile) + { + //delete[] casefile; // used if it is an array, created with "new" + //delete casefile; // used if it is not an array, created with "new" + casefile = NULL; // needed after "delete" for objects pointed to by pointers that are created with "new" // technically it is not needed if it is a pointer created without calls to "new" + } + u0.deallocate(); v0.deallocate(); w0.deallocate(); @@ -4516,6 +4527,16 @@ void ninja::set_position(double lat_degrees, double lat_minutes, double lat_seco "less than -180 degrees in ninja::set_position()."); } +/** + * Set the pointer to the shared casefile. + * + * @param a casefile class passed in as a reference + */ +void ninja::set_casefilePtr( CaseFile &theCaseFile ) +{ + casefile = &theCaseFile; +} + void ninja::set_numberCPUs(int CPUs) { if(CPUs < 1) diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index fb5616be..ec1cb731 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -60,12 +60,12 @@ #include "ninja_conv.h" -#include "casefile.h" #include "constants.h" #include "ascii_grid.h" #include "SurfProperties.h" #include "surfaceVectorField.h" #include "WindNinjaInputs.h" +#include "casefile.h" #include "KmlVector.h" #include "ShapeVector.h" #include "preconditioner.h" @@ -134,6 +134,7 @@ class ninja Mesh mesh; std::string casefilename; + CaseFile* casefile; //output grids to access the final wind grids (typically used by other programs running the windninja API such as WFDSS, FlamMap, etc. AsciiGridAngleGrid; @@ -309,6 +310,7 @@ class ninja void set_position(double lat_degrees, double lat_minutes, double long_degrees, double long_minutes); //input as degrees, decimal minutes void set_position(double lat_degrees, double lat_minutes, double lat_seconds, double long_degrees, double long_minutes, double long_seconds); //input as degrees, minutes, seconds + void set_casefilePtr( CaseFile &theCaseFile ); void set_numberCPUs(int CPUs); double *get_outputSpeedGrid(); double *get_outputDirectionGrid(); diff --git a/src/ninja/ninjaArmy.cpp b/src/ninja/ninjaArmy.cpp index d7d3a844..c51613df 100644 --- a/src/ninja/ninjaArmy.cpp +++ b/src/ninja/ninjaArmy.cpp @@ -1296,6 +1296,13 @@ int ninjaArmy::setPosition( const int nIndex, char ** papszOptions ) IF_VALID_INDEX_TRY( nIndex, ninjas, ninjas[ nIndex ]->set_position() ); } +int ninjaArmy::setCaseFilePtr( const int nIndex, CaseFile &casefile, + char ** papszOptions ) +{ + IF_VALID_INDEX_TRY( nIndex, ninjas, + ninjas[ nIndex ]->set_casefilePtr( casefile ) ); +} + int ninjaArmy::setNumberCPUs( const int nIndex, const int nCPUs, char ** papszOptions ) { IF_VALID_INDEX_TRY( nIndex, ninjas, ninjas[ nIndex ]->set_numberCPUs( nCPUs ) ); diff --git a/src/ninja/ninjaArmy.h b/src/ninja/ninjaArmy.h index ceb9a2c7..18fa54b8 100644 --- a/src/ninja/ninjaArmy.h +++ b/src/ninja/ninjaArmy.h @@ -48,6 +48,7 @@ #include "boost/typeof/typeof.hpp" #endif #include "WindNinjaInputs.h" +#include "casefile.h" #include "fetch_factory.h" namespace blt = boost::local_time; @@ -504,6 +505,16 @@ class ninjaArmy char ** papszOptions=NULL ); int setPosition( const int nIndex, char ** papszOptions=NULL ); + /** + * \brief Set the pointer to the shared casefile of a ninja + * + * \param nIndex index of a ninja + * \param a casefile class passed in as a reference + * \return errval Returns NINJA_SUCCESS upon success + */ + int setCaseFilePtr( const int nIndex, CaseFile &casefile, + char ** papszOptions=NULL ); + /** * \brief Set the input speed grid filename from a NinjaFOAM run for use with diurnal * diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 3994c79b..df43fe7b 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2647,9 +2647,8 @@ void NinjaFoam::WriteOutputFiles() try{ - CaseFile casefile; // write mass mesh if casefile is turned on - casefile always needs a vtk - if (writeMassMeshVtk == true || casefile.getZipOpen()) + if (writeMassMeshVtk == true || casefile->getZipOpen()) { CPLDebug("NINJAFOAM", "writing mass mesh vtk output for foam simulation."); writeMassMeshVtkOutput(); @@ -2702,36 +2701,35 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); - CaseFile casefile; std::string directoryPath = get_outputPath(); - std::string normfile = casefile.parse("file", massMeshVtkFilename); - std::string directoryofVTK = casefile.parse("directory", massMeshVtkFilename); - std::string surfFile = casefile.parse("file", massMeshVtkFilename).substr(0, casefile.parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile.parse("file", massMeshVtkFilename).substr(casefile.parse("file", massMeshVtkFilename).length() - 4, casefile.parse("file", massMeshVtkFilename).length()); - if( casefile.getZipOpen() ) + std::string normfile = casefile->parse("file", massMeshVtkFilename); + std::string directoryofVTK = casefile->parse("directory", massMeshVtkFilename); + std::string surfFile = casefile->parse("file", massMeshVtkFilename).substr(0, casefile->parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile->parse("file", massMeshVtkFilename).substr(casefile->parse("file", massMeshVtkFilename).length() - 4, casefile->parse("file", massMeshVtkFilename).length()); + if( casefile->getZipOpen() ) { - casefile.rename(casefilename); + casefile->rename(casefilename); std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) { - std::string getlocaltime = casefile.getTime(); + std::string getlocaltime = casefile->getTime(); timestr = getlocaltime; } else { timestr = converttimetostd(input.ninjaTime); } - std::string zipFilePath = casefile.getzip(); - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, massMeshVtkFilename); - casefile.addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + std::string zipFilePath = casefile->getzip(); + casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, massMeshVtkFilename); + casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); } if( writeMassMeshVtk == false ) { - ////casefile.deleteFileFromPath(directoryPath, normfile); - ////casefile.deleteFileFromPath(directoryPath, surfFile); - casefile.deleteFileFromPath(directoryofVTK, normfile); - casefile.deleteFileFromPath(directoryofVTK, surfFile); + ////casefile->deleteFileFromPath(directoryPath, normfile); + ////casefile->deleteFileFromPath(directoryPath, surfFile); + casefile->deleteFileFromPath(directoryofVTK, normfile); + casefile->deleteFileFromPath(directoryofVTK, surfFile); } } catch (exception& e) { @@ -3783,9 +3781,8 @@ void NinjaFoam::SetMeshResolutionAndResampleDem() } - CaseFile casefile; // write mass mesh if casefile is turned on - casefile always needs a vtk - if (writeMassMeshVtk == true || casefile.getZipOpen()) { + if (writeMassMeshVtk == true || casefile->getZipOpen()) { // need to setup mesh sizing BEFORE the dem gets resampled, but AFTER the mesh resolution gets set massMesh.set_numVertLayers(20); // done in cli.cpp calling ninja_army calling ninja calling this function, with windsim.setNumVertLayers( i_, 20); where i_ is ninjaIdx CPLDebug("NINJAFOAM", "mass mesh vtk output set by mesh resolution, %f %s", meshResolution, lengthUnits::getString(meshResolutionUnits).c_str()); From 1df0527f0b32e0fa99e83c687463603615265df7 Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 20 Mar 2025 16:26:22 -0600 Subject: [PATCH 19/35] 2nd cleanup attempt of casefile stuff mostly just rearranging the casefile.h/.cpp to a slightly more coherent order before I start messing with variable names and editing functions for issue #7 --- src/gui/mainWindow.cpp | 10 ++- src/ninja/casefile.cpp | 200 +++++++++++++++++++++-------------------- src/ninja/casefile.h | 52 ++++++----- src/ninja/ninja.cpp | 9 -- 4 files changed, 141 insertions(+), 130 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 542cee07..401c5b5b 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -2711,6 +2711,7 @@ int mainWindow::solve() std::vector times = tree->weather->timeList(); /* This can throw a badForecastFile */ + std::cout << "weather times.size() = " << times.size() << std::endl; if (writeCF && times.size() > 0) { std::vector stringTimes; @@ -2782,7 +2783,14 @@ int mainWindow::solve() //get times for casefile if no times are clicked by user if (writeCF && times.size() == 0) { - std::vector wxtimesfromcasefile = casefile.getWXTIME(); // is this even used??? I do not see even one setTimeWX() instance in the code before this spot + // TODO: casefile.setWxTime() for this instance needs to be called somewhere, currently casefile.getWxTime() just returns an empty list, + // yet, if the user purposefully unselects all times to select no input time, the code runs ALL the times in the forecast + // even better, replace casefile.setWxTime() and casefile.getWxTime() with a call to get the full weather forecast time list from some gui file somewhere + // started this, found that the list of times is already set and grabbable, but need to convert it from a QStringList into boost local_date_time objects + QStringList QString_wxTimesList = tree->weather->timeModel->stringList(); + std::cout << "QString_wxTimesList.size() = " << QString_wxTimesList.size() << std::endl; + + std::vector wxtimesfromcasefile = casefile.getWxTimes(); std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 93d2f10f..ccdb4464 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -1,44 +1,57 @@ #include "casefile.h" -//std::mutex zipMutex; +std::mutex zipMutex; + CaseFile::CaseFile() { - zipfilename = ""; - directory = ""; zipalreadyopened = false; + directory = ""; + zipfilename = ""; downloadedfromdem = false; elevsource = ""; } -bool CaseFile::isCfgFile(const std::string& filePath) + +void CaseFile::setZipOpen(bool zipopen) { - const std::string extension = ".cfg"; - if (filePath.length() >= extension.length()) + if (zipopen) { - std::string fileExtension = filePath.substr(filePath.length() - extension.length()); - return fileExtension == extension; + zipalreadyopened = true; } else { - return false; + zipalreadyopened = false; } } -bool CaseFile::isVTKFile(const std::string& filePath) +bool CaseFile::getZipOpen() { - const std::string extension = ".vtk"; - if (filePath.length() >= extension.length()) - { - std::string fileExtension = filePath.substr(filePath.length() - extension.length()); - return fileExtension == extension; - } else - { - return false; - } + return zipalreadyopened; +} + +void CaseFile::setdir(std::string dir) +{ + directory = dir; +} + +std::string CaseFile::getdir() +{ + return directory; +} + +void CaseFile::setzip(std::string zip) +{ + zipfilename = zip; } -bool CaseFile::lookforzip(const std::string& zipFilePath, const std::string& directory) +std::string CaseFile::getzip() +{ + return zipfilename; +} + + +bool CaseFile::lookForZip(const std::string& zipFilePath, const std::string& directory) { char** papszDir = VSIReadDir(directory.c_str()); if (papszDir != nullptr) @@ -62,42 +75,12 @@ bool CaseFile::lookforzip(const std::string& zipFilePath, const std::string& dir return false; } -bool CaseFile::lookfordate(const std::string& date) -{ - return false; -} - -std::string CaseFile::parse(const std::string& type, const std::string& path) -{ - size_t found = path.find_last_of("/"); - if (found != std::string::npos) - { - if (strcmp(type.c_str(), "directory") == 0) - { - return path.substr(0, found); - } else - { - if (strcmp(type.c_str(), "file") == 0) - { - return path.substr(found + 1); // Extract substring after the last '/' - } - } - } else - { - //std::cout << "couldn't parse" << std::endl; - //return ""; - return path; - } -} - -void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath) +void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrLocalPath) { - // CPL logging enabled here - //std::lock_guard lock(zipMutex); // for multithreading issue - //CPLSetConfigOption("CPL_DEBUG", "ON"); + std::lock_guard lock(zipMutex); // for multithreading issue try { - bool foundzip = lookforzip(zipFilePath, dirPath); + bool foundzip = lookForZip(zipFilePath, dirPath); if (foundzip) { @@ -132,10 +115,10 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d return; } - VSILFILE *file = VSIFOpenL(usrlocalpath.c_str(), "rb"); + VSILFILE *file = VSIFOpenL(usrLocalPath.c_str(), "rb"); if (file == nullptr) { - CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", usrlocalpath.c_str()); + CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", usrLocalPath.c_str()); cpl_zipCloseFileInZip(zip); cpl_zipClose(zip, nullptr); return; @@ -190,18 +173,6 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d } } -std::string CaseFile::getTime() -{ - auto now = std::chrono::system_clock::now(); - std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); - - std::tm* local_tm = std::localtime(&now_time_t); - - std::ostringstream oss; - oss << std::put_time(local_tm, "%Y-%m-%d %H:%M:%S"); - return oss.str(); -} - // to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name void CaseFile::rename(std::string newname) { @@ -246,55 +217,87 @@ void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filenam } } -void CaseFile::setdir(std::string dir) + +std::string CaseFile::parse(const std::string& type, const std::string& path) { - directory = dir; + size_t found = path.find_last_of("/"); + if (found != std::string::npos) + { + if (strcmp(type.c_str(), "directory") == 0) + { + return path.substr(0, found); + } else + { + if (strcmp(type.c_str(), "file") == 0) + { + return path.substr(found + 1); // Extract substring after the last '/' + } + } + } else + { + //std::cout << "couldn't parse" << std::endl; + //return ""; + return path; + } } -std::string CaseFile::getzip() +std::string CaseFile::convertDateTime(const boost::local_time::local_date_time& ninjaTime) { - return zipfilename; + return ""; } -void CaseFile::setzip(std::string zip) +bool CaseFile::lookForDate(const std::string& date) { - zipfilename = zip; + return false; } -std::string CaseFile::getdir() +std::string CaseFile::getTime() { - return directory; + auto now = std::chrono::system_clock::now(); + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + + std::tm* local_tm = std::localtime(&now_time_t); + + std::ostringstream oss; + oss << std::put_time(local_tm, "%Y-%m-%d %H:%M:%S"); + return oss.str(); } -void CaseFile::setZipOpen(bool zipopen) +bool CaseFile::isCfgFile(const std::string& filePath) { - if (zipopen) + const std::string extension = ".cfg"; + if (filePath.length() >= extension.length()) { - zipalreadyopened = true; + std::string fileExtension = filePath.substr(filePath.length() - extension.length()); + return fileExtension == extension; } else { - zipalreadyopened = false; + return false; } } -bool CaseFile::getZipOpen() +bool CaseFile::isVTKFile(const std::string& filePath) { - return zipalreadyopened; + const std::string extension = ".vtk"; + if (filePath.length() >= extension.length()) + { + std::string fileExtension = filePath.substr(filePath.length() - extension.length()); + return fileExtension == extension; + } else + { + return false; + } } -void CaseFile::setTimeWX(std::vector timeList) -{ - timesforWX = timeList; -} -std::vector CaseFile::getWXTIME() +void CaseFile::setDownloadedFromDem(bool downloadedfromdemm) { - return timesforWX; + downloadedfromdem = downloadedfromdemm; } -void CaseFile::setBoundingBox(std::vector boundingboxarrr) +bool CaseFile::getDownloadedFromDem() { - boundingboxarr = boundingboxarrr; + return downloadedfromdem; } void CaseFile::setElevSource(std::string elevsourcee) @@ -302,22 +305,27 @@ void CaseFile::setElevSource(std::string elevsourcee) elevsource = elevsourcee; } -void CaseFile::setDownloadedFromDEM(bool downloadedfromdemm) -{ - downloadedfromdem = downloadedfromdemm; -} - std::string CaseFile::getElevSource() { return elevsource; } -bool CaseFile::getDownloadedFromDEM() +void CaseFile::setBoundingBox(std::vector boundingboxarrr) { - return downloadedfromdem; + boundingboxarr = boundingboxarrr; } std::vector CaseFile::getBoundingBox() { return boundingboxarr; } + +void CaseFile::setWxTimes(std::vector timeList) +{ + timesForWx = timeList; +} + +std::vector CaseFile::getWxTimes() +{ + return timesForWx; +} diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index e73805e7..62b6e91e 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -43,7 +43,7 @@ #include #include #include -//#include +#include #include class CaseFile @@ -55,49 +55,53 @@ class CaseFile std::string directory; std::string zipfilename; - std::vector timesforWX; - std::vector boundingboxarr; bool downloadedfromdem; std::string elevsource; + std::vector boundingboxarr; + + std::vector timesForWx; public: + CaseFile(); - void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrlocalpath); - void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); - bool lookforzip(const std::string& zipFilePath, const std::string& directory); - bool isCfgFile(const std::string& filePath); - bool isVTKFile(const std::string& filePath); - - std::string parse(const std::string& type, const std::string& path); - std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); - bool lookfordate(const std::string& date); + void setZipOpen(bool zipopen); + bool getZipOpen(); - std::string getTime(); - void rename(std::string newname); - std::string getdir(); void setdir(std::string dir); + std::string getdir(); - std::string getzip(); void setzip(std::string zip); + std::string getzip(); - void setZipOpen(bool zipopen); - bool getZipOpen(); - void setTimeWX(std::vector timeList); - std::vector getWXTIME(); + bool lookForZip(const std::string& zipFilePath, const std::string& directory); + void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrLocalPath); + void rename(std::string newname); + void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); - void setBoundingBox(std::vector boundingboxarrr); - void setElevSource(std::string elevsourcee); + std::string parse(const std::string& type, const std::string& path); + std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); + bool lookForDate(const std::string& date); + std::string getTime(); + bool isCfgFile(const std::string& filePath); + bool isVTKFile(const std::string& filePath); + - void setDownloadedFromDEM(bool downloadedfromdemm); + void setDownloadedFromDem(bool downloadedfromdemm); + bool getDownloadedFromDem(); + void setElevSource(std::string elevsourcee); std::string getElevSource(); - bool getDownloadedFromDEM(); + void setBoundingBox(std::vector boundingboxarrr); std::vector CaseFile::getBoundingBox(); + + void setWxTimes(std::vector timeList); + std::vector getWxTimes(); + }; #endif /* CASEFILE_H */ diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 5bdb3923..7a4f2771 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -172,7 +172,6 @@ ninja::ninja(const ninja &rhs) solar=NULL; casefilename = rhs.casefilename; - //casefile = NULL; // ONLY DO THIS IF WANTING THE MEMORY TO BE RESET TO A DEFAULT VALUE EVEN DURING COPY/OPERATOR=. Not wanted for this case, using this for diurnal sims loses the pointer casefile = rhs.casefile; } @@ -252,7 +251,6 @@ ninja &ninja::operator=(const ninja &rhs) solar=NULL; casefilename = rhs.casefilename; - //casefile = NULL; // ONLY DO THIS IF WANTING THE MEMORY TO BE RESET TO A DEFAULT VALUE EVEN DURING COPY/OPERATOR=. Not wanted for this case, using this for diurnal sims loses the pointer casefile = rhs.casefile; } return *this; @@ -3311,13 +3309,6 @@ void ninja::deleteDynamicMemory() outputDirectionArray = NULL; } - if(casefile) - { - //delete[] casefile; // used if it is an array, created with "new" - //delete casefile; // used if it is not an array, created with "new" - casefile = NULL; // needed after "delete" for objects pointed to by pointers that are created with "new" // technically it is not needed if it is a pointer created without calls to "new" - } - u0.deallocate(); v0.deallocate(); w0.deallocate(); From 064daa43aa78f64c78841c054958f3cb2dff0abd Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 20 Mar 2025 19:23:52 -0600 Subject: [PATCH 20/35] 2nd cleanup attempt of casefile stuff continued removing the use and need of dirPath/directory in all the casefile stuff, after attempting to make sure that each of the dirPath/directory variables used everywhere in cli.cpp, mainWindow.cpp, ninja.cpp, and ninjafoam.cpp match up to be the same as well as match up to be the same as the case zip file directory also some more variable name changes, had to be careful though because zipFile was already being used as a variable name, and in particular was the class name of the mini_zip stuff this was surprisingly annoying to do, led to a lot of changes all over the place. But the result should make the code way more readable and easier to edit for future changes, including replacing existing functions with simpler cross-platform functions the bigger challenge is how cli.cpp is handling/setting the outputDir used by the zip file, it doesn't remain consistent in how it is set later in the code, kind of a chicken before the egg situation going on in that particular place in the code for issue #7 --- src/gui/mainWindow.cpp | 34 +++++++-------- src/ninja/casefile.cpp | 94 +++++++++++++++++------------------------ src/ninja/casefile.h | 24 +++++------ src/ninja/cli.cpp | 32 +++++++++----- src/ninja/ninja.cpp | 20 ++++----- src/ninja/ninjafoam.cpp | 22 +++++----- 6 files changed, 109 insertions(+), 117 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 401c5b5b..00933a58 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1662,6 +1662,7 @@ int mainWindow::solve() CaseFile casefile; std::string getdir = tree->solve->outputDirectory().toStdString(); + std::cout << "getdir = \"" << getdir << "\"" << std::endl; std::string inputpath = getdir + "/config.cfg"; std::string getfileName = casefile.parse("file", inputFileName.toStdString()); @@ -1670,9 +1671,8 @@ int mainWindow::solve() std::string zipFilePath = getdir + "/tmp.ninja"; - casefile.setZipOpen(true); - casefile.setdir(getdir); - casefile.setzip(zipFilePath); + casefile.setIsZipOpen(true); + casefile.setCaseZipFile(zipFilePath); std::ofstream outFile(inputpath); @@ -1692,9 +1692,9 @@ int mainWindow::solve() outFile.close(); stationCSVFILE.close(); - casefile.setZipOpen(false); - casefile.deleteFileFromPath(getdir, "config.cfg"); - casefile.deleteFileFromPath(getdir, "selectedstations.csv"); + casefile.setIsZipOpen(false); + casefile.deleteFile( getdir + "/config.cfg" ); + casefile.deleteFile( getdir + "/selectedstations.csv" ); } #ifdef NINJAFOAM @@ -2426,10 +2426,10 @@ int mainWindow::solve() std::string pointpath2 = "pointinitialization/" + tokens[tokens.size()-1]; if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - casefile.addFileToZip(zipFilePath, getdir, pointpath1, pfile); + casefile.addFileToZip(zipFilePath, pointpath1, pfile); } else { - casefile.addFileToZip(zipFilePath, getdir, pointpath2, pfile); + casefile.addFileToZip(zipFilePath, pointpath2, pfile); } } } @@ -2450,7 +2450,7 @@ int mainWindow::solve() } stationCSVFILE.close(); std::string pointpathusual = "pointinitialization/selectedstations.csv"; - casefile.addFileToZip(zipFilePath, getdir, pointpathusual, stationCSVFILEPATH); + casefile.addFileToZip(zipFilePath, pointpathusual, stationCSVFILEPATH); } // if (writeCF) @@ -2741,7 +2741,7 @@ int mainWindow::solve() outFile << "--forecast_times " << outstr << "\n"; outFile << "--forecast_filename " << weatherFile << "\n"; std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); - casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); + casefile.addFileToZip(zipFilePath, weatherFileName, weatherFile); } // if (writeCF && times.size() > 0) try @@ -2818,7 +2818,7 @@ int mainWindow::solve() outFile << "--forecast_times " << outstr << "\n"; outFile << "--forecast_filename " << weatherFile << "\n"; std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); - casefile.addFileToZip(zipFilePath, getdir, weatherFileName, weatherFile); + casefile.addFileToZip(zipFilePath, weatherFileName, weatherFile); } // if (writeCF && times.size() == 0) nRuns = army->getSize(); @@ -3060,10 +3060,10 @@ int mainWindow::solve() { if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { - casefile.addFileToZip(zipFilePath, getdir, domainaveragepath, domaininputpath ); + casefile.addFileToZip(zipFilePath, domainaveragepath, domaininputpath ); } } - casefile.deleteFileFromPath(getdir, domainaveragedeletion ); + casefile.deleteFile( getdir + "/" + domainaveragedeletion ); } // for(int i = 0;i < army->getSize(); i++) @@ -3071,10 +3071,10 @@ int mainWindow::solve() if (writeCF) { outFile.close(); - casefile.addFileToZip(zipFilePath, getdir, getfileName, inputFileName.toStdString()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); - casefile.deleteFileFromPath(getdir, "selectedstations.csv"); + casefile.addFileToZip(zipFilePath, getfileName, inputFileName.toStdString()); + casefile.addFileToZip(zipFilePath, "config.cfg", inputpath); + casefile.deleteFile( getdir + "/config.cfg" ); + casefile.deleteFile( getdir + "/selectedstations.csv" ); } army->set_writeFarsiteAtmFile( writeAtm && writeFb ); diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index ccdb4464..d8746aae 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -5,54 +5,55 @@ std::mutex zipMutex; CaseFile::CaseFile() { - zipalreadyopened = false; - directory = ""; - zipfilename = ""; + isZipOpen = false; + caseZipFile = ""; downloadedfromdem = false; elevsource = ""; } -void CaseFile::setZipOpen(bool zipopen) +void CaseFile::setIsZipOpen(bool isZippOpen) { - if (zipopen) - { - zipalreadyopened = true; - } else - { - zipalreadyopened = false; - } -} - -bool CaseFile::getZipOpen() -{ - return zipalreadyopened; + isZipOpen = isZippOpen; } -void CaseFile::setdir(std::string dir) +bool CaseFile::getIsZipOpen() { - directory = dir; + return isZipOpen; } -std::string CaseFile::getdir() +void CaseFile::setCaseZipFile(std::string caseZippFile) { - return directory; + caseZipFile = caseZippFile; } -void CaseFile::setzip(std::string zip) +std::string CaseFile::getCaseZipFile() { - zipfilename = zip; + return caseZipFile; } -std::string CaseFile::getzip() +// to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name +void CaseFile::renameCaseZipFile(std::string newCaseZipFile) { - return zipfilename; + if (parse("file", caseZipFile) == "tmp.ninja") + { + if (VSIRename(caseZipFile.c_str(), newCaseZipFile.c_str()) == 0) + { + CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", caseZipFile.c_str(), newCaseZipFile.c_str()); + caseZipFile = newCaseZipFile; + } else + { + CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", caseZipFile.c_str(), newCaseZipFile.c_str()); + } + } } -bool CaseFile::lookForZip(const std::string& zipFilePath, const std::string& directory) +// not as redundant as deleteFile(), but close, seems to be more like a, doesZipFileExist() type function +bool CaseFile::lookForZip(const std::string& zipFilePath) { + std::string directory = parse("directory", zipFilePath); char** papszDir = VSIReadDir(directory.c_str()); if (papszDir != nullptr) { @@ -65,7 +66,7 @@ bool CaseFile::lookForZip(const std::string& zipFilePath, const std::string& dir continue; } - if (entry == parse("file", getzip())) + if (entry == parse("file", getCaseZipFile())) { return true; } @@ -75,12 +76,12 @@ bool CaseFile::lookForZip(const std::string& zipFilePath, const std::string& dir return false; } -void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrLocalPath) +void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& withinZipPathedFilename, const std::string& fileToAdd) { std::lock_guard lock(zipMutex); // for multithreading issue try { - bool foundzip = lookForZip(zipFilePath, dirPath); + bool foundzip = lookForZip(zipFilePath); if (foundzip) { @@ -108,17 +109,17 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d } zip_fileinfo zi = {0}; - if (cpl_zipOpenNewFileInZip(zip, fileToAdd.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) + if (cpl_zipOpenNewFileInZip(zip, withinZipPathedFilename.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { - CPLDebug("ZIP", "Could not open new file in ZIP: %s", fileToAdd.c_str()); + CPLDebug("ZIP", "Could not open new file in ZIP: %s", withinZipPathedFilename.c_str()); cpl_zipClose(zip, nullptr); return; } - VSILFILE *file = VSIFOpenL(usrLocalPath.c_str(), "rb"); + VSILFILE *file = VSIFOpenL(fileToAdd.c_str(), "rb"); if (file == nullptr) { - CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", usrLocalPath.c_str()); + CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", fileToAdd.c_str()); cpl_zipCloseFileInZip(zip); cpl_zipClose(zip, nullptr); return; @@ -140,7 +141,7 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d if (VSIFReadL(data, 1, fileSize, file) != fileSize) { - CPLDebug("FileRead", "Failed to read file contents: %s", fileToAdd.c_str()); + CPLDebug("FileRead", "Failed to read file contents: %s", withinZipPathedFilename.c_str()); CPLFree(data); VSIFCloseL(file); cpl_zipCloseFileInZip(zip); @@ -150,7 +151,7 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) { - CPLDebug("ZIP", "Error writing data to ZIP file: %s", fileToAdd.c_str()); + CPLDebug("ZIP", "Error writing data to ZIP file: %s", withinZipPathedFilename.c_str()); } CPLFree(data); @@ -173,27 +174,10 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& d } } -// to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name -void CaseFile::rename(std::string newname) -{ - if (parse("file", zipfilename) == "tmp.ninja") - { - std::string oldFilePath = zipfilename; - std::string newFilePath = newname; - - if (VSIRename(oldFilePath.c_str(), newFilePath.c_str()) == 0) - { - CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", oldFilePath.c_str(), newFilePath.c_str()); - zipfilename = newname; - } else - { - CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", oldFilePath.c_str(), newFilePath.c_str()); - } - } -} - -void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filename) +// becomes redundant, probs should just call VSIUnlink on the file itself +void CaseFile::deleteFile(std::string file) { + std::string directoryPath = parse("directory", file); char** papszDir = VSIReadDir(directoryPath.c_str()); if (papszDir != nullptr) { @@ -208,7 +192,7 @@ void CaseFile::deleteFileFromPath(std::string directoryPath, std::string filenam std::string fullPath = directoryPath + "/" + entry; - if (entry == filename) + if (fullPath == file) { VSIUnlink(fullPath.c_str()); } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 62b6e91e..4a7e2cf6 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -51,9 +51,8 @@ class CaseFile private: - bool zipalreadyopened; - std::string directory; - std::string zipfilename; + bool isZipOpen; + std::string caseZipFile; bool downloadedfromdem; std::string elevsource; @@ -66,20 +65,17 @@ class CaseFile CaseFile(); - void setZipOpen(bool zipopen); - bool getZipOpen(); + void setIsZipOpen(bool isZippOpen); + bool getIsZipOpen(); - void setdir(std::string dir); - std::string getdir(); + void setCaseZipFile(std::string caseZippFile); + std::string getCaseZipFile(); + void renameCaseZipFile(std::string newCaseZipFile); - void setzip(std::string zip); - std::string getzip(); - - bool lookForZip(const std::string& zipFilePath, const std::string& directory); - void addFileToZip(const std::string& zipFilePath, const std::string& dirPath, const std::string& fileToAdd, const std::string& usrLocalPath); - void rename(std::string newname); - void deleteFileFromPath(std::string directoryPath, std::string filenameToDelete); + bool lookForZip(const std::string& zipFilePath); + void addFileToZip(const std::string& zipFilePath, const std::string& withinZipPathedFilename, const std::string& fileToAdd); + void deleteFile(std::string file); std::string parse(const std::string& type, const std::string& path); diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 085f7e00..294d5e47 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -462,7 +462,20 @@ int windNinjaCLI(int argc, char* argv[]) CaseFile casefile; if (vm["write_casefile"].as() == true) { - std::string getdir = casefile.parse( "directory", vm["elevation_file"].as()); + std::string getdir = vm.count("output_path") ? vm["output_path"].as().c_str() : ""; + std::cout << "getdir = \"" << getdir << "\"" << std::endl; + if( vm.count("output_path") ) + { + getdir = vm["output_path"].as(); + } else // if (getdir == "") + { + // hrm, should work, but it isn't ideal. searches for "customOutputPath" in ninjafoam.cpp and ninja.cpp show + // that this is correct to keep paths all the same EXCEPT for with weather model initialization, which uses + // input.forecastFilename instead unless it is not set as an input, THEN it uses the dem file + // it is not an easy thing to make sure we have forecastFilename here in the code the same way as later in the code + getdir = casefile.parse( "directory", vm["elevation_file"].as()); + } + std::cout << "getdir = \"" << getdir << "\"" << std::endl; std::string inputpath = getdir + "/config.cfg"; std::ofstream outFile(inputpath); @@ -508,22 +521,21 @@ int windNinjaCLI(int argc, char* argv[]) std::string zipFilePath = getdir + "/tmp.ninja"; - casefile.setZipOpen(true); - casefile.setdir(getdir); - casefile.setzip(zipFilePath); + casefile.setIsZipOpen(true); + casefile.setCaseZipFile(zipFilePath); // This flush is actually optional because close() will flush automatically outFile.flush(); outFile.close(); - casefile.addFileToZip(zipFilePath, getdir, getconfigname, vm["config_file"].as()); - casefile.addFileToZip(zipFilePath, getdir, getfileName, vm["elevation_file"].as()); - casefile.addFileToZip(zipFilePath, getdir, "config.cfg", inputpath); - casefile.deleteFileFromPath(getdir, "config.cfg"); + casefile.addFileToZip(zipFilePath, getconfigname, vm["config_file"].as()); + casefile.addFileToZip(zipFilePath, getfileName, vm["elevation_file"].as()); + casefile.addFileToZip(zipFilePath, "config.cfg", inputpath); + casefile.deleteFile( getdir + "/config.cfg" ); if (vm.count("forecast_filename")) { std::string getweatherFileName = "weatherfile/" + casefile.parse("file", vm["forecast_filename"].as()); - casefile.addFileToZip(zipFilePath, getdir, getweatherFileName, vm["forecast_filename"].as()); + casefile.addFileToZip(zipFilePath, getweatherFileName, vm["forecast_filename"].as()); } if (vm.count("wx_station_filename")) { @@ -537,7 +549,7 @@ int windNinjaCLI(int argc, char* argv[]) } } - casefile.addFileToZip(zipFilePath, getdir, getpointFileName, vm["wx_station_filename"].as()); + casefile.addFileToZip(zipFilePath, getpointFileName, vm["wx_station_filename"].as()); } } diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 7a4f2771..20cac1a7 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2810,7 +2810,7 @@ void ninja::writeOutputFiles() //Write volume data to VTK format (always in m/s?) //write to casefile regardless of if VTK is checked - if(input.volVTKOutFlag == true || casefile->getZipOpen()) + if(input.volVTKOutFlag == true || casefile->getIsZipOpen()) { try{ bool vtk_out_as_utm = false; @@ -2826,9 +2826,9 @@ void ninja::writeOutputFiles() std::string normfile = casefile->parse("file", input.volVTKFile); std::string directoryofVTK = casefile->parse("directory", input.volVTKFile); std::string surfFile = casefile->parse("file", input.volVTKFile).substr(0, casefile->parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile->parse("file", input.volVTKFile).substr(casefile->parse("file", input.volVTKFile).length() - 4, casefile->parse("file", input.volVTKFile).length()); - if( casefile->getZipOpen() ) + if( casefile->getIsZipOpen() ) { - casefile->rename(casefilename); + casefile->renameCaseZipFile(casefilename); std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) @@ -2840,17 +2840,17 @@ void ninja::writeOutputFiles() timestr = converttimetostd(input.ninjaTime); } - std::string zipFilePath = casefile->getzip(); - casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, input.volVTKFile); - casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + std::string zipFilePath = casefile->getCaseZipFile(); + casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + normfile, input.volVTKFile); + casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); } if( input.volVTKOutFlag == false ) { - //casefile->deleteFileFromPath(directoryPath, normfile); - //casefile->deleteFileFromPath(directoryPath, surfFile); - casefile->deleteFileFromPath(directoryofVTK, normfile); - casefile->deleteFileFromPath(directoryofVTK, surfFile); + //casefile->deleteFile( directoryPath + "/" + normfile ); + //casefile->deleteFile( directoryPath + "/" + surfFile ); + casefile->deleteFile( directoryofVTK + "/" + normfile ); + casefile->deleteFile( directoryofVTK + "/" + surfFile ); } }catch (exception& e) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index df43fe7b..e9ba48a3 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2648,7 +2648,7 @@ void NinjaFoam::WriteOutputFiles() try{ // write mass mesh if casefile is turned on - casefile always needs a vtk - if (writeMassMeshVtk == true || casefile->getZipOpen()) + if (writeMassMeshVtk == true || casefile->getIsZipOpen()) { CPLDebug("NINJAFOAM", "writing mass mesh vtk output for foam simulation."); writeMassMeshVtkOutput(); @@ -2705,9 +2705,9 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string normfile = casefile->parse("file", massMeshVtkFilename); std::string directoryofVTK = casefile->parse("directory", massMeshVtkFilename); std::string surfFile = casefile->parse("file", massMeshVtkFilename).substr(0, casefile->parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile->parse("file", massMeshVtkFilename).substr(casefile->parse("file", massMeshVtkFilename).length() - 4, casefile->parse("file", massMeshVtkFilename).length()); - if( casefile->getZipOpen() ) + if( casefile->getIsZipOpen() ) { - casefile->rename(casefilename); + casefile->renameCaseZipFile(casefilename); std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) @@ -2719,17 +2719,17 @@ void NinjaFoam::writeMassMeshVtkOutput() timestr = converttimetostd(input.ninjaTime); } - std::string zipFilePath = casefile->getzip(); - casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + normfile, massMeshVtkFilename); - casefile->addFileToZip(zipFilePath, directoryPath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + std::string zipFilePath = casefile->getCaseZipFile(); + casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + normfile, massMeshVtkFilename); + casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); } if( writeMassMeshVtk == false ) { - ////casefile->deleteFileFromPath(directoryPath, normfile); - ////casefile->deleteFileFromPath(directoryPath, surfFile); - casefile->deleteFileFromPath(directoryofVTK, normfile); - casefile->deleteFileFromPath(directoryofVTK, surfFile); + ////casefile->deleteFile( directoryPath + "/" + normfile ); + ////casefile->deleteFile( directoryPath + "/" + surfFile ); + casefile->deleteFile( directoryofVTK + "/" + normfile ); + casefile->deleteFile( directoryofVTK + "/" + surfFile ); } } catch (exception& e) { @@ -3782,7 +3782,7 @@ void NinjaFoam::SetMeshResolutionAndResampleDem() // write mass mesh if casefile is turned on - casefile always needs a vtk - if (writeMassMeshVtk == true || casefile->getZipOpen()) { + if (writeMassMeshVtk == true || casefile->getIsZipOpen()) { // need to setup mesh sizing BEFORE the dem gets resampled, but AFTER the mesh resolution gets set massMesh.set_numVertLayers(20); // done in cli.cpp calling ninja_army calling ninja calling this function, with windsim.setNumVertLayers( i_, 20); where i_ is ninjaIdx CPLDebug("NINJAFOAM", "mass mesh vtk output set by mesh resolution, %f %s", meshResolution, lengthUnits::getString(meshResolutionUnits).c_str()); From a84eab1c653b3eaceb91bb9dde7060bab36c2c7b Mon Sep 17 00:00:00 2001 From: latwood Date: Fri, 21 Mar 2025 11:38:49 -0600 Subject: [PATCH 21/35] 2nd cleanup attempt of casefile stuff continued, 1st pass replacing functions with cross-platform style functions --- src/gui/mainWindow.cpp | 11 ++++---- src/ninja/casefile.cpp | 59 +++-------------------------------------- src/ninja/casefile.h | 2 -- src/ninja/cli.cpp | 2 +- src/ninja/ninja.cpp | 12 ++++----- src/ninja/ninjafoam.cpp | 12 ++++----- 6 files changed, 19 insertions(+), 79 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 00933a58..80d8a68f 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1693,8 +1693,8 @@ int mainWindow::solve() stationCSVFILE.close(); casefile.setIsZipOpen(false); - casefile.deleteFile( getdir + "/config.cfg" ); - casefile.deleteFile( getdir + "/selectedstations.csv" ); + VSIUnlink( inputpath.c_str() ); + VSIUnlink( stationCSVFILEPATH.c_str() ); } #ifdef NINJAFOAM @@ -3055,7 +3055,6 @@ int mainWindow::solve() //add different input to config domainRUNS.close(); std::string domainaveragepath = "DomainAverage/run" + std::to_string(i) + ".cfg"; - std::string domainaveragedeletion = "domainrun" + std::to_string(i) + ".cfg"; if (writeCF) { if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) @@ -3063,7 +3062,7 @@ int mainWindow::solve() casefile.addFileToZip(zipFilePath, domainaveragepath, domaininputpath ); } } - casefile.deleteFile( getdir + "/" + domainaveragedeletion ); + VSIUnlink( domaininputpath.c_str() ); } // for(int i = 0;i < army->getSize(); i++) @@ -3073,8 +3072,8 @@ int mainWindow::solve() outFile.close(); casefile.addFileToZip(zipFilePath, getfileName, inputFileName.toStdString()); casefile.addFileToZip(zipFilePath, "config.cfg", inputpath); - casefile.deleteFile( getdir + "/config.cfg" ); - casefile.deleteFile( getdir + "/selectedstations.csv" ); + VSIUnlink( inputpath.c_str() ); + VSIUnlink( stationCSVFILEPATH.c_str() ); } army->set_writeFarsiteAtmFile( writeAtm && writeFb ); diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index d8746aae..13247cef 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -50,40 +50,14 @@ void CaseFile::renameCaseZipFile(std::string newCaseZipFile) } -// not as redundant as deleteFile(), but close, seems to be more like a, doesZipFileExist() type function -bool CaseFile::lookForZip(const std::string& zipFilePath) -{ - std::string directory = parse("directory", zipFilePath); - char** papszDir = VSIReadDir(directory.c_str()); - if (papszDir != nullptr) - { - for (int i = 0; papszDir[i] != nullptr; i++) - { - std::string entry = papszDir[i]; - - if (entry == "." || entry == "..") - { - continue; - } - - if (entry == parse("file", getCaseZipFile())) - { - return true; - } - } - CSLDestroy(papszDir); - } - return false; -} - void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& withinZipPathedFilename, const std::string& fileToAdd) { std::lock_guard lock(zipMutex); // for multithreading issue try { - bool foundzip = lookForZip(zipFilePath); + bool doesZipExist = CPLCheckForFile(zipFilePath.c_str(), NULL); - if (foundzip) + if (doesZipExist) { std::ifstream infile(zipFilePath); if (!infile.good()) @@ -94,7 +68,7 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& w } zipFile zip; - if (!foundzip) + if (!doesZipExist) { zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_CREATE); } else @@ -174,33 +148,6 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& w } } -// becomes redundant, probs should just call VSIUnlink on the file itself -void CaseFile::deleteFile(std::string file) -{ - std::string directoryPath = parse("directory", file); - char** papszDir = VSIReadDir(directoryPath.c_str()); - if (papszDir != nullptr) - { - for (int i = 0; papszDir[i] != nullptr; i++) - { - std::string entry = papszDir[i]; - - if (entry == "." || entry == "..") - { - continue; - } - - std::string fullPath = directoryPath + "/" + entry; - - if (fullPath == file) - { - VSIUnlink(fullPath.c_str()); - } - } - CSLDestroy(papszDir); - } -} - std::string CaseFile::parse(const std::string& type, const std::string& path) { diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 4a7e2cf6..2662d6a9 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -73,9 +73,7 @@ class CaseFile void renameCaseZipFile(std::string newCaseZipFile); - bool lookForZip(const std::string& zipFilePath); void addFileToZip(const std::string& zipFilePath, const std::string& withinZipPathedFilename, const std::string& fileToAdd); - void deleteFile(std::string file); std::string parse(const std::string& type, const std::string& path); diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 294d5e47..4f1716a2 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -531,7 +531,7 @@ int windNinjaCLI(int argc, char* argv[]) casefile.addFileToZip(zipFilePath, getconfigname, vm["config_file"].as()); casefile.addFileToZip(zipFilePath, getfileName, vm["elevation_file"].as()); casefile.addFileToZip(zipFilePath, "config.cfg", inputpath); - casefile.deleteFile( getdir + "/config.cfg" ); + VSIUnlink( inputpath.c_str() ); if (vm.count("forecast_filename")) { std::string getweatherFileName = "weatherfile/" + casefile.parse("file", vm["forecast_filename"].as()); diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 20cac1a7..24f621fc 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2822,10 +2822,10 @@ void ninja::writeOutputFiles() std::string vtkWriteFormat = "binary";//"binary";//"ascii"; volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string directoryPath = get_outputPath(); std::string normfile = casefile->parse("file", input.volVTKFile); std::string directoryofVTK = casefile->parse("directory", input.volVTKFile); - std::string surfFile = casefile->parse("file", input.volVTKFile).substr(0, casefile->parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile->parse("file", input.volVTKFile).substr(casefile->parse("file", input.volVTKFile).length() - 4, casefile->parse("file", input.volVTKFile).length()); + std::string volVtkSurfFilename = casefile->parse("file", input.volVTKFile).substr(0, casefile->parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile->parse("file", input.volVTKFile).substr(casefile->parse("file", input.volVTKFile).length() - 4, casefile->parse("file", input.volVTKFile).length()); + std::string volVtkSurfFile = directoryofVTK + "/" + volVtkSurfFilename; if( casefile->getIsZipOpen() ) { casefile->renameCaseZipFile(casefilename); @@ -2842,15 +2842,13 @@ void ninja::writeOutputFiles() std::string zipFilePath = casefile->getCaseZipFile(); casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + normfile, input.volVTKFile); - casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + volVtkSurfFilename, volVtkSurfFile); } if( input.volVTKOutFlag == false ) { - //casefile->deleteFile( directoryPath + "/" + normfile ); - //casefile->deleteFile( directoryPath + "/" + surfFile ); - casefile->deleteFile( directoryofVTK + "/" + normfile ); - casefile->deleteFile( directoryofVTK + "/" + surfFile ); + VSIUnlink( input.volVTKFile.c_str() ); + VSIUnlink( volVtkSurfFile.c_str() ); } }catch (exception& e) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index e9ba48a3..6a0c0c01 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2701,10 +2701,10 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); - std::string directoryPath = get_outputPath(); std::string normfile = casefile->parse("file", massMeshVtkFilename); std::string directoryofVTK = casefile->parse("directory", massMeshVtkFilename); - std::string surfFile = casefile->parse("file", massMeshVtkFilename).substr(0, casefile->parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile->parse("file", massMeshVtkFilename).substr(casefile->parse("file", massMeshVtkFilename).length() - 4, casefile->parse("file", massMeshVtkFilename).length()); + std::string massMeshVtkSurfFilename = casefile->parse("file", massMeshVtkFilename).substr(0, casefile->parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile->parse("file", massMeshVtkFilename).substr(casefile->parse("file", massMeshVtkFilename).length() - 4, casefile->parse("file", massMeshVtkFilename).length()); + std::string massMeshVtkSurfFile = directoryofVTK + "/" + massMeshVtkSurfFilename; if( casefile->getIsZipOpen() ) { casefile->renameCaseZipFile(casefilename); @@ -2721,15 +2721,13 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string zipFilePath = casefile->getCaseZipFile(); casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + normfile, massMeshVtkFilename); - casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + surfFile, directoryofVTK + "/" + surfFile); + casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + massMeshVtkSurfFilename, massMeshVtkSurfFile); } if( writeMassMeshVtk == false ) { - ////casefile->deleteFile( directoryPath + "/" + normfile ); - ////casefile->deleteFile( directoryPath + "/" + surfFile ); - casefile->deleteFile( directoryofVTK + "/" + normfile ); - casefile->deleteFile( directoryofVTK + "/" + surfFile ); + VSIUnlink( massMeshVtkFilename.c_str() ); + VSIUnlink( massMeshVtkSurfFile.c_str() ); } } catch (exception& e) { From 16ae1b51476f90dc06c095e1977d7d27a133a8c4 Mon Sep 17 00:00:00 2001 From: latwood Date: Fri, 21 Mar 2025 16:05:22 -0600 Subject: [PATCH 22/35] 2nd cleanup attempt of casefile stuff continued, renamed a lot of variables and filenames, for issue #7 I'm still not the most happy with the new naming schemes, some of the names are starting to get a bit too long, and while they are now easier to differentiate from one another while more similar/consistent between files, some of them are still too similar to each other for my tests. Ah well, good enough for now. --- src/gui/mainWindow.cpp | 396 +++++++++++++++++++++------------------- src/ninja/casefile.cpp | 16 +- src/ninja/casefile.h | 2 +- src/ninja/cli.cpp | 105 ++++++----- src/ninja/ninja.cpp | 12 +- src/ninja/ninjafoam.cpp | 20 +- 6 files changed, 292 insertions(+), 259 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 80d8a68f..426733ae 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1657,50 +1657,64 @@ void mainWindow::openOutputPath() int mainWindow::solve() { + + std::string outputDir = tree->solve->outputDirectory().toStdString(); + if( outputDir == "" ) { + // This should never happen, so if it does, fix it. + throw( "no output directory specified in solve page" ); + } + std::cout << "output_path = \"" << outputDir << "\"" << std::endl; + + bool writeCF = tree->solve->CaseFileBox->isChecked(); CaseFile casefile; - std::string getdir = tree->solve->outputDirectory().toStdString(); - std::cout << "getdir = \"" << getdir << "\"" << std::endl; - std::string inputpath = getdir + "/config.cfg"; + std::string mainCaseCfgFilename = "config.cfg"; + std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; - std::string getfileName = casefile.parse("file", inputFileName.toStdString()); + std::string demFilename = casefile.parse("file", demFile); - std::string stationCSVFILEPATH = getdir + "/selectedstations.csv"; + std::string selectedStationsFilename = "selected_stations.csv"; + std::string selectedStationsFile = outputDir + "/" + selectedStationsFilename; - std::string zipFilePath = getdir + "/tmp.ninja"; + std::string zipFile = outputDir + "/tmp.ninja"; casefile.setIsZipOpen(true); - casefile.setCaseZipFile(zipFilePath); + casefile.setCaseZipFile(zipFile); - std::ofstream outFile(inputpath); + std::ofstream mainCaseCfgFILE(mainCaseCfgFile); - std::ofstream stationCSVFILE(stationCSVFILEPATH); + std::ofstream selectedStationsFILE(selectedStationsFile); - if (!outFile) { + if (!mainCaseCfgFILE) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; } - if (!stationCSVFILE) { + if (!selectedStationsFILE) { std::cerr << "Error: Could not open the file for writing!" << std::endl; return 1; } if (!writeCF) { - outFile.close(); - stationCSVFILE.close(); + mainCaseCfgFILE.close(); + selectedStationsFILE.close(); casefile.setIsZipOpen(false); - VSIUnlink( inputpath.c_str() ); - VSIUnlink( stationCSVFILEPATH.c_str() ); + VSIUnlink( mainCaseCfgFile.c_str() ); + VSIUnlink( selectedStationsFile.c_str() ); + } + + + if (writeCF) { + mainCaseCfgFILE << "--output_path " << outputDir << "\n"; } #ifdef NINJAFOAM bool useNinjaFoam = tree->ninjafoam->ninjafoamGroupBox->isChecked(); if (writeCF && useNinjaFoam) { - outFile << "--momentum_flag true\n"; + mainCaseCfgFILE << "--momentum_flag true\n"; } #endif //disable the open output path button @@ -1712,23 +1726,23 @@ int mainWindow::solve() if (writeCF) { if (demWidget != NULL && demWidget->get_wasDemFetched() == true) { - outFile << "--fetch_elevation true" << "\n"; - outFile << "--north " << demWidget->get_northBound() << "\n"; - outFile << "--south " << demWidget->get_southBound() << "\n"; - outFile << "--west " << demWidget->get_westBound() << "\n"; - outFile << "--east " << demWidget->get_eastBound() << "\n"; - outFile << "--elevation_source " << demWidget->get_elevSource() << "\n"; + mainCaseCfgFILE << "--fetch_elevation true" << "\n"; + mainCaseCfgFILE << "--north " << demWidget->get_northBound() << "\n"; + mainCaseCfgFILE << "--south " << demWidget->get_southBound() << "\n"; + mainCaseCfgFILE << "--west " << demWidget->get_westBound() << "\n"; + mainCaseCfgFILE << "--east " << demWidget->get_eastBound() << "\n"; + mainCaseCfgFILE << "--elevation_source " << demWidget->get_elevSource() << "\n"; } else { - outFile << "--fetch_elevation false" << "\n"; + mainCaseCfgFILE << "--fetch_elevation false" << "\n"; } - outFile << "--elevation_file " << demFile << "\n"; + mainCaseCfgFILE << "--elevation_file " << demFile << "\n"; } #ifdef NINJAFOAM std::string caseFile = existingCaseDir.toStdString(); if (writeCF && useNinjaFoam) { - outFile << "--existing_case_directory" << caseFile << "\n"; + mainCaseCfgFILE << "--existing_case_directory" << caseFile << "\n"; } #endif @@ -1742,19 +1756,19 @@ int mainWindow::solve() { vegetation = WindNinjaInputs::grass; if (writeCF) { - outFile << "--vegetation grass\n"; + mainCaseCfgFILE << "--vegetation grass\n"; } } else if( vegIndex == 1 ) { vegetation = WindNinjaInputs::brush; if (writeCF) { - outFile << "--vegetation brush\n"; + mainCaseCfgFILE << "--vegetation brush\n"; } } else if( vegIndex == 2 ) { vegetation = WindNinjaInputs::trees; if (writeCF) { - outFile << "--vegetation trees\n"; + mainCaseCfgFILE << "--vegetation trees\n"; } } } @@ -1769,19 +1783,19 @@ int mainWindow::solve() { meshChoice = Mesh::coarse; if (writeCF) { - outFile << "--mesh_choice coarse\n"; + mainCaseCfgFILE << "--mesh_choice coarse\n"; } } else if( meshIndex == 1 ) { meshChoice = Mesh::medium; if (writeCF) { - outFile << "--mesh_choice medium\n"; + mainCaseCfgFILE << "--mesh_choice medium\n"; } } else if( meshIndex == 2 ) { meshChoice = Mesh::fine; if (writeCF) { - outFile << "--mesh_choice fine\n"; + mainCaseCfgFILE << "--mesh_choice fine\n"; } } else { @@ -1793,18 +1807,18 @@ int mainWindow::solve() { meshUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_mesh_resolution ft\n"; + mainCaseCfgFILE << "--units_mesh_resolution ft\n"; } } else { meshUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_mesh_resolution m\n"; + mainCaseCfgFILE << "--units_mesh_resolution m\n"; } } if (writeCF && customMesh) { - outFile << "--mesh_resolution " << std::to_string(meshRes) << "\n"; + mainCaseCfgFILE << "--mesh_resolution " << std::to_string(meshRes) << "\n"; } #ifdef NINJAFOAM @@ -1848,7 +1862,7 @@ int mainWindow::solve() QVariant temp = tree->surface->timeZone->tzComboBox->itemData( tzIndex ); std::string timeZone = temp.toString().toStdString(); if (writeCF) { - outFile << "--time_zone " << timeZone << "\n"; + mainCaseCfgFILE << "--time_zone " << timeZone << "\n"; } //diurnal @@ -1860,17 +1874,17 @@ int mainWindow::solve() if (writeCF) { if (useDiurnal == 0) { - outFile << "--diurnal_winds false\n"; + mainCaseCfgFILE << "--diurnal_winds false\n"; } else { - outFile << "--diurnal_winds true\n"; + mainCaseCfgFILE << "--diurnal_winds true\n"; } if (useStability == 0) { - outFile << "--non_neutral_stability false\n"; + mainCaseCfgFILE << "--non_neutral_stability false\n"; } else { - outFile << "--non_neutral_stability true\n"; + mainCaseCfgFILE << "--non_neutral_stability true\n"; } } @@ -1880,39 +1894,39 @@ int mainWindow::solve() { initMethod = WindNinjaInputs::domainAverageInitializationFlag; if (writeCF) { - outFile << "--initialization_method domainAverageInitialization\n"; + mainCaseCfgFILE << "--initialization_method domainAverageInitialization\n"; } } else if( tree->point->pointGroupBox->isChecked() ) { initMethod = WindNinjaInputs::pointInitializationFlag; if (writeCF) { - outFile << "--initialization_method pointInitialization\n"; + mainCaseCfgFILE << "--initialization_method pointInitialization\n"; } } else if( tree->weather->weatherGroupBox->isChecked() ) { initMethod = WindNinjaInputs::wxModelInitializationFlag; if (writeCF) { - outFile << "--initialization_method wxModelInitialization\n"; + mainCaseCfgFILE << "--initialization_method wxModelInitialization\n"; } } //input wind height double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); if (writeCF) { - outFile << "--input_wind_height " << std::to_string(inHeight) << "\n"; + mainCaseCfgFILE << "--input_wind_height " << std::to_string(inHeight) << "\n"; } lengthUnits::eLengthUnits inHeightUnits; if(tree->wind->metaWind->feetRadioButton->isChecked()) { inHeightUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_input_wind_height ft\n"; + mainCaseCfgFILE << "--units_input_wind_height ft\n"; } } else { inHeightUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_input_wind_height m\n"; + mainCaseCfgFILE << "--units_input_wind_height m\n"; } } @@ -1922,25 +1936,25 @@ int mainWindow::solve() { inputSpeedUnits = velocityUnits::milesPerHour; if (writeCF) { - outFile << "--input_speed_units mph\n"; + mainCaseCfgFILE << "--input_speed_units mph\n"; } } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 1) { inputSpeedUnits = velocityUnits::metersPerSecond; if (writeCF) { - outFile << "--input_speed_units mps\n"; + mainCaseCfgFILE << "--input_speed_units mps\n"; } } else if(tree->wind->windTable->inputSpeedUnits->currentIndex() == 3) { inputSpeedUnits = velocityUnits::knots; if (writeCF) { - outFile << "--input_speed_units kts\n"; + mainCaseCfgFILE << "--input_speed_units kts\n"; } } else { inputSpeedUnits = velocityUnits::kilometersPerHour; if (writeCF) { - outFile << "--input_speed_units kph\n" ; + mainCaseCfgFILE << "--input_speed_units kph\n"; } } @@ -1949,13 +1963,13 @@ int mainWindow::solve() { tempUnits = temperatureUnits::F; if (writeCF) { - outFile << "--air_temp_units F\n" ; + mainCaseCfgFILE << "--air_temp_units F\n"; } } else if(tree->wind->windTable->airTempUnits->currentIndex() == 1) { tempUnits = temperatureUnits::C; if (writeCF) { - outFile << "--air_temp_units C\n"; + mainCaseCfgFILE << "--air_temp_units C\n"; } } @@ -1967,8 +1981,8 @@ int mainWindow::solve() QFileInfo fi( tree->weather->model->fileInfo( mi ) ); weatherFile = fi.absoluteFilePath().toStdString(); if (writeCF) { - outFile << "--wx_model_type "; - outFile << "--forecast_duration " << tree->weather->hourSpinBox->value() << "\n"; + mainCaseCfgFILE << "--wx_model_type "; + mainCaseCfgFILE << "--forecast_duration " << tree->weather->hourSpinBox->value() << "\n"; } } else { @@ -1978,20 +1992,20 @@ int mainWindow::solve() //output height double outHeight = tree->output->outputHeight->outputHeightDoubleSpinBox->value(); if (writeCF) { - outFile << "--output_wind_height " << std::to_string(outHeight) << "\n"; + mainCaseCfgFILE << "--output_wind_height " << std::to_string(outHeight) << "\n"; } lengthUnits::eLengthUnits outHeightUnits; if(tree->output->outputHeight->feetRadioButton->isChecked()) { outHeightUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_output_wind_height ft\n"; + mainCaseCfgFILE << "--units_output_wind_height ft\n"; } } else { outHeightUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_output_wind_height m\n"; + mainCaseCfgFILE << "--units_output_wind_height m\n"; } } @@ -2000,25 +2014,25 @@ int mainWindow::solve() { outputSpeedUnits = velocityUnits::milesPerHour; if (writeCF) { - outFile << "--output_speed_units mph\n"; + mainCaseCfgFILE << "--output_speed_units mph\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 1) { outputSpeedUnits = velocityUnits::metersPerSecond; if (writeCF) { - outFile << "--output_speed_units mps\n" ; + mainCaseCfgFILE << "--output_speed_units mps\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 2) { outputSpeedUnits = velocityUnits::kilometersPerHour; if (writeCF) { - outFile << "--output_speed_units kph\n"; + mainCaseCfgFILE << "--output_speed_units kph\n"; } } else if(tree->output->outputSpeedUnitsCombo->currentIndex() == 3) { outputSpeedUnits = velocityUnits::knots; if (writeCF) { - outFile << "--output_speed_units kts\n"; + mainCaseCfgFILE << "--output_speed_units kts\n"; } } @@ -2027,7 +2041,7 @@ int mainWindow::solve() if (writeCF) { //if (clip > 0) //{ - outFile << "--output_buffer_clipping " << std::to_string(clip) << "\n"; + mainCaseCfgFILE << "--output_buffer_clipping " << std::to_string(clip) << "\n"; //} } @@ -2041,12 +2055,12 @@ int mainWindow::solve() if (writeCF) { if (writeGoogle) { - outFile << "--write_goog_output true\n"; + mainCaseCfgFILE << "--write_goog_output true\n"; if( initMethod == WindNinjaInputs::wxModelInitializationFlag) { - outFile << "--write_wx_model_goog_output true\n"; + mainCaseCfgFILE << "--write_wx_model_goog_output true\n"; } - outFile << "--goog_out_resolution " << std::to_string(googleRes) << "\n"; + mainCaseCfgFILE << "--goog_out_resolution " << std::to_string(googleRes) << "\n"; } } double vectorWidth = tree->google->vectorWidthDoubleSpinBox->value(); @@ -2057,13 +2071,13 @@ int mainWindow::solve() { googleUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_goog_out_resolution m\n"; + mainCaseCfgFILE << "--units_goog_out_resolution m\n"; } } else { googleUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_goog_out_resolution ft\n"; + mainCaseCfgFILE << "--units_goog_out_resolution ft\n"; } } if(tree->google->uniformRangeRadioButton->isChecked()) @@ -2079,10 +2093,10 @@ int mainWindow::solve() if (writeCF) { if (googVectorScaling) { - outFile << "--goog_out_vector_scaling true\n"; + mainCaseCfgFILE << "--goog_out_vector_scaling true\n"; } else { - outFile << "--goog_out_vector_scaling false\n"; + mainCaseCfgFILE << "--goog_out_vector_scaling false\n"; } } if(tree->google->colorblindBox->isChecked()) @@ -2095,63 +2109,63 @@ int mainWindow::solve() { googleScheme="default"; if (writeCF) { - outFile << "--goog_out_color_scheme ROYGB\n"; + mainCaseCfgFILE << "--goog_out_color_scheme ROYGB\n"; } } if (googCheckScheme=="ROPGW (Red Orange Pink Green White)") { googleScheme="ROPGW"; if (writeCF) { - outFile << "--goog_out_color_scheme ROPGW\n"; + mainCaseCfgFILE << "--goog_out_color_scheme ROPGW\n"; } } if (googCheckScheme=="Oranges") { googleScheme="oranges"; if (writeCF) { - outFile << "--goog_out_color_scheme oranges\n"; + mainCaseCfgFILE << "--goog_out_color_scheme oranges\n"; } } if (googCheckScheme=="Blues") { googleScheme="blues"; if (writeCF) { - outFile << "--goog_out_color_scheme blues\n"; + mainCaseCfgFILE << "--goog_out_color_scheme blues\n"; } } if (googCheckScheme=="Pinks") { googleScheme="pinks"; if (writeCF) { - outFile << "--goog_out_color_scheme pinks\n"; + mainCaseCfgFILE << "--goog_out_color_scheme pinks\n"; } } if (googCheckScheme=="Greens") { googleScheme="greens"; if (writeCF) { - outFile << "--goog_out_color_scheme greens\n"; + mainCaseCfgFILE << "--goog_out_color_scheme greens\n"; } } if (googCheckScheme=="Magic Beans") { googleScheme="magic_beans"; if (writeCF) { - outFile << "--goog_out_color_scheme magic_beans\n"; + mainCaseCfgFILE << "--goog_out_color_scheme magic_beans\n"; } } if (googCheckScheme=="Pink to Green") { googleScheme="pink_to_green"; if (writeCF) { - outFile << "--goog_out_color_scheme pink_to_green\n"; + mainCaseCfgFILE << "--goog_out_color_scheme pink_to_green\n"; } } } else { googleScheme="default"; if (writeCF) { - outFile << "--goog_out_color_scheme ROYGB\n"; + mainCaseCfgFILE << "--goog_out_color_scheme ROYGB\n"; } } @@ -2161,12 +2175,12 @@ int mainWindow::solve() if (writeCF) { if (writeFb) { - outFile << "--write_ascii_output true\n"; + mainCaseCfgFILE << "--write_ascii_output true\n"; if (initMethod == WindNinjaInputs::wxModelInitializationFlag ) { - outFile << "--write_wx_model_ascii_output true\n"; + mainCaseCfgFILE << "--write_wx_model_ascii_output true\n"; } - outFile << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; + mainCaseCfgFILE << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; } } lengthUnits::eLengthUnits fbUnits; @@ -2174,13 +2188,13 @@ int mainWindow::solve() { fbUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_ascii_out_resolution m\n"; + mainCaseCfgFILE << "--units_ascii_out_resolution m\n"; } } else { fbUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_ascii_out_resolution ft\n"; + mainCaseCfgFILE << "--units_ascii_out_resolution ft\n"; } } @@ -2189,7 +2203,7 @@ int mainWindow::solve() if (writeCF) { if (writeAtm) { - outFile << "--write_farsite_atm true\n"; + mainCaseCfgFILE << "--write_farsite_atm true\n"; } } if(writeAtm && writeFb) @@ -2223,12 +2237,12 @@ int mainWindow::solve() if (writeCF) { if (writeShape) { - outFile << "--write_shapefile_output true\n"; + mainCaseCfgFILE << "--write_shapefile_output true\n"; if( initMethod == WindNinjaInputs::wxModelInitializationFlag ) { - outFile << "--write_wx_model_shapefile_output true\n"; + mainCaseCfgFILE << "--write_wx_model_shapefile_output true\n"; } - outFile << "--shape_out_resolution " << std::to_string(shapeRes) << "\n"; + mainCaseCfgFILE << "--shape_out_resolution " << std::to_string(shapeRes) << "\n"; } } lengthUnits::eLengthUnits shapeUnits; @@ -2236,13 +2250,13 @@ int mainWindow::solve() { shapeUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_shape_out_resolution m\n"; + mainCaseCfgFILE << "--units_shape_out_resolution m\n"; } } else { shapeUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_shape_out_resolution ft\n"; + mainCaseCfgFILE << "--units_shape_out_resolution ft\n"; } } @@ -2253,9 +2267,9 @@ int mainWindow::solve() if (writeCF) { if (writePdf) { - outFile << "--write_pdf_output true\n"; - outFile << "--pdf_out_resolution "<< std::to_string(pdfRes) << "\n"; - outFile << "--pdf_linewidth "<< std::to_string(pdfLineWidth) << "\n"; + mainCaseCfgFILE << "--write_pdf_output true\n"; + mainCaseCfgFILE << "--pdf_out_resolution "<< std::to_string(pdfRes) << "\n"; + mainCaseCfgFILE << "--pdf_linewidth "<< std::to_string(pdfLineWidth) << "\n"; } } lengthUnits::eLengthUnits pdfUnits; @@ -2263,23 +2277,23 @@ int mainWindow::solve() { pdfUnits = lengthUnits::meters; if (writeCF) { - outFile << "--units_pdf_out_resolution m\n"; + mainCaseCfgFILE << "--units_pdf_out_resolution m\n"; } } else { pdfUnits = lengthUnits::feet; if (writeCF) { - outFile << "--units_pdf_out_resolution ft\n"; + mainCaseCfgFILE << "--units_pdf_out_resolution ft\n"; } } int pdfBase = tree->pdf->backgroundComboBox->currentIndex(); if (writeCF) { if (pdfBase == 0) { - outFile << "--pdf_basemap topofire\n"; + mainCaseCfgFILE << "--pdf_basemap topofire\n"; } else { - outFile << "--pdf_basemap hillshade\n"; + mainCaseCfgFILE << "--pdf_basemap hillshade\n"; } } double pdfHeight, pdfWidth; @@ -2290,7 +2304,7 @@ int mainWindow::solve() pdfHeight = 11.0; pdfWidth = 8.5; if (writeCF) { - outFile << "--pdf_size letter\n"; + mainCaseCfgFILE << "--pdf_size letter\n"; } } // Legal @@ -2299,7 +2313,7 @@ int mainWindow::solve() pdfHeight = 14.0; pdfWidth = 8.5; if (writeCF) { - outFile << "--pdf_size legal\n"; + mainCaseCfgFILE << "--pdf_size legal\n"; } } // Tabloid @@ -2308,7 +2322,7 @@ int mainWindow::solve() pdfHeight = 17.0; pdfWidth = 11.0; if (writeCF) { - outFile << "--pdf_size tabloid\n"; + mainCaseCfgFILE << "--pdf_size tabloid\n"; } } if( tree->pdf->landscapeRadioButton->isChecked() ) @@ -2323,14 +2337,14 @@ int mainWindow::solve() if (writeCF) { if (writeVTK) { - outFile << "--write_vtk_output true\n"; + mainCaseCfgFILE << "--write_vtk_output true\n"; } } //number of processors int nThreads = tree->solve->numProcSpinBox->value(); if (writeCF) { - outFile << "--num_threads " << std::to_string(nThreads) << "\n"; + mainCaseCfgFILE << "--num_threads " << std::to_string(nThreads) << "\n"; } #ifdef NINJAFOAM @@ -2356,101 +2370,103 @@ int mainWindow::solve() { if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) { - outFile << "--fetch_station true\n"; - outFile << "--fetch_type " << tree->point->xWidget->getType() << "\n"; + mainCaseCfgFILE << "--fetch_station true\n"; + mainCaseCfgFILE << "--fetch_type " << tree->point->xWidget->getType() << "\n"; if (tree->point->xWidget->getType() == "bbox") { - outFile << "--station_buffer " << tree->point->xWidget->getBuffer() << "\n"; - outFile << "--station_buffer_units " << tree->point->xWidget->getBufferUnits() << "\n"; + mainCaseCfgFILE << "--station_buffer " << tree->point->xWidget->getBuffer() << "\n"; + mainCaseCfgFILE << "--station_buffer_units " << tree->point->xWidget->getBufferUnits() << "\n"; } if (tree->point->xWidget->getType() == "stid") { - outFile << "--fetch_station_name " << tree->point->xWidget->getStationIDS() << "\n"; + mainCaseCfgFILE << "--fetch_station_name " << tree->point->xWidget->getStationIDS() << "\n"; } if (tree->point->xWidget->get_isTimeSeries() == false) { - outFile << "--fetch_current_station_data true\n"; + mainCaseCfgFILE << "--fetch_current_station_data true\n"; } else { - outFile << "--fetch_current_station_data false\n"; - outFile << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + mainCaseCfgFILE << "--fetch_current_station_data false\n"; + mainCaseCfgFILE << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; } } else // if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) { - outFile << "--fetch_station false\n"; + mainCaseCfgFILE << "--fetch_station false\n"; if (useTimeList) { - outFile << "--fetch_current_station_data false\n"; - outFile << "--start_year " << xStartTime[0] << "\n"; - outFile << "--start_month " << xStartTime[1] << "\n"; - outFile << "--start_day " << xStartTime[2] << "\n"; - outFile << "--start_hour " << xStartTime[3] << "\n"; - outFile << "--start_minute " << xStartTime[4] << "\n"; - outFile << "--stop_year " << xEndTime[0] << "\n"; - outFile << "--stop_month " << xEndTime[1] << "\n"; - outFile << "--stop_day " << xEndTime[2] << "\n"; - outFile << "--stop_hour " << xEndTime[3] << "\n"; - outFile << "--stop_minute " << xEndTime[4] << "\n"; - outFile << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + mainCaseCfgFILE << "--fetch_current_station_data false\n"; + mainCaseCfgFILE << "--start_year " << xStartTime[0] << "\n"; + mainCaseCfgFILE << "--start_month " << xStartTime[1] << "\n"; + mainCaseCfgFILE << "--start_day " << xStartTime[2] << "\n"; + mainCaseCfgFILE << "--start_hour " << xStartTime[3] << "\n"; + mainCaseCfgFILE << "--start_minute " << xStartTime[4] << "\n"; + mainCaseCfgFILE << "--stop_year " << xEndTime[0] << "\n"; + mainCaseCfgFILE << "--stop_month " << xEndTime[1] << "\n"; + mainCaseCfgFILE << "--stop_day " << xEndTime[2] << "\n"; + mainCaseCfgFILE << "--stop_hour " << xEndTime[3] << "\n"; + mainCaseCfgFILE << "--stop_minute " << xEndTime[4] << "\n"; + mainCaseCfgFILE << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; } else { - outFile << "--fetch_current_station_data true\n"; + mainCaseCfgFILE << "--fetch_current_station_data true\n"; } } // if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) if (writeStationKML) { - outFile << "--write_wx_station_kml true\n"; + mainCaseCfgFILE << "--write_wx_station_kml true\n"; } else { - outFile << "--write_wx_station_kml false\n"; + mainCaseCfgFILE << "--write_wx_station_kml false\n"; } if (writeStationCSV) { - outFile << "--write_wx_station_csv true\n"; + mainCaseCfgFILE << "--write_wx_station_csv true\n"; } else { - outFile << "--write_wx_station_csv false\n"; + mainCaseCfgFILE << "--write_wx_station_csv false\n"; } // for each file append it to csv // if any point file is under a wx station folder just copy the entire folder over - otherwise no std::vector fullFileListPoint = tree->point->fullFileList; - for (std::string & pfile : fullFileListPoint) + for (std::string & pointFile : fullFileListPoint) { - std::vector tokens = split(pfile, "/"); + std::vector tokens = split(pointFile, "/"); if (tokens.size() >= 2) { std::string secondToLastToken = tokens[tokens.size()-2]; - std::string pointpath1 = "pointinitialization/" + tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1]; - std::string pointpath2 = "pointinitialization/" + tokens[tokens.size()-1]; + std::string pointFilename1 = tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1]; + std::string pointFilename2 = tokens[tokens.size()-1]; + std::string pointZipPathFile1 = "PointInitialization/" + pointFilename1; + std::string pointZipPathFile2 = "PointInitialization/" + pointFilename2; if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - casefile.addFileToZip(zipFilePath, pointpath1, pfile); + casefile.addFileToZip(zipFile, pointZipPathFile1, pointFile); } else { - casefile.addFileToZip(zipFilePath, pointpath2, pfile); + casefile.addFileToZip(zipFile, pointZipPathFile2, pointFile); } } } // setup list of actually used/selected stations - for (std::string & pfile : pointFileList) + for (std::string & pointFile : pointFileList) { - std::vector tokens = split(pfile, "/"); - std::string updatedpath = casefile.parse("file", pfile); + std::vector tokens = split(pointFile, "/"); + std::string pointFilename = casefile.parse("file", pointFile); if (tokens.size() >= 2) { std::string secondToLastToken = tokens[tokens.size()-2]; if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - updatedpath = secondToLastToken + "/" + tokens[tokens.size() - 1]; + pointFilename = secondToLastToken + "/" + tokens[tokens.size() - 1]; } } - stationCSVFILE << updatedpath << "\n"; + selectedStationsFILE << pointFilename << "\n"; } - stationCSVFILE.close(); - std::string pointpathusual = "pointinitialization/selectedstations.csv"; - casefile.addFileToZip(zipFilePath, pointpathusual, stationCSVFILEPATH); + selectedStationsFILE.close(); + std::string selectedStationsZipPathFile = "PointInitialization/" + selectedStationsFilename; + casefile.addFileToZip(zipFile, selectedStationsZipPathFile, selectedStationsFile); } // if (writeCF) @@ -2500,7 +2516,7 @@ int mainWindow::solve() } try{ //Try to run windninja if (writeCF) { - outFile << "--match_points true\n"; + mainCaseCfgFILE << "--match_points true\n"; } army->makeStationArmy(timeList,timeZone, pointFile, demFile, true,false); } @@ -2559,7 +2575,7 @@ int mainWindow::solve() try{ //try running with timelist if (writeCF) { - outFile << "--match_points true\n"; + mainCaseCfgFILE << "--match_points true\n"; } army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); //setting pointFileList[0] is just for header checks etc } @@ -2595,7 +2611,7 @@ int mainWindow::solve() pointInitialization::storeFileNames(pointFileList); try{ //try making the army with current data if (writeCF) { - outFile << "--match_points true\n"; + mainCaseCfgFILE << "--match_points true\n"; } army->makeStationArmy(timeList,timeZone,pointFileList[0],demFile,true,false); } @@ -2673,8 +2689,8 @@ int mainWindow::solve() std::string metaPath = std::string(CPLFormFilename(pathDem.c_str(),baseMeta.c_str(),".csv")); CPLDebug("STATION_FETCH","Saving Metadata to: %s",metaPath.c_str()); if (writeCF) { - outFile << "--fetch_metadata true\n"; - outFile << "--metadata_filename" << metaPath << "\n"; + mainCaseCfgFILE << "--fetch_metadata true\n"; + mainCaseCfgFILE << "--metadata_filename" << metaPath << "\n"; } pointInitialization::fetchMetaData(metaPath,demFile,true); } @@ -2738,10 +2754,11 @@ int mainWindow::solve() } } - outFile << "--forecast_times " << outstr << "\n"; - outFile << "--forecast_filename " << weatherFile << "\n"; - std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); - casefile.addFileToZip(zipFilePath, weatherFileName, weatherFile); + mainCaseCfgFILE << "--forecast_times " << outstr << "\n"; + mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; + std::string weatherFilename = casefile.parse("file", weatherFile); + std::string weatherZipPathFile = "WxModelInitialization/" + weatherFilename; + casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); } // if (writeCF && times.size() > 0) try @@ -2815,10 +2832,11 @@ int mainWindow::solve() } } - outFile << "--forecast_times " << outstr << "\n"; - outFile << "--forecast_filename " << weatherFile << "\n"; - std::string weatherFileName = "weatherfile/" + casefile.parse("file", weatherFile); - casefile.addFileToZip(zipFilePath, weatherFileName, weatherFile); + mainCaseCfgFILE << "--forecast_times " << outstr << "\n"; + mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; + std::string weatherFilename = casefile.parse("file", weatherFile); + std::string weatherZipPathFile = "WxModelInitialization/" + weatherFilename; + casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); } // if (writeCF && times.size() == 0) nRuns = army->getSize(); @@ -2829,38 +2847,30 @@ int mainWindow::solve() progressDialog->setRange(0, nRuns * 100); //Expand the dialog to the number of runs runProgress = new int[nRuns]; //I don't think this is needed anymore - std::string outputDir = tree->solve->outputDirectory().toStdString(); - if (writeCF) { - outFile << "--output_path " << outputDir << "\n"; - } - if( outputDir == "" ) { - // This should never happen, so if it does, fix it. - throw( "no output directory specified in solve page" ); - } - //fill in the values for(int i = 0;i < army->getSize(); i++) { army->setCaseFilePtr( i, casefile ); - std::string domaininputpath = getdir + "/domainrun" + std::to_string(i) + ".cfg"; - std::ofstream domainRUNS(domaininputpath); + std::string domainRunCfgFilename = "run" + std::to_string(i) + "-DomainAverage.cfg"; + std::string domainRunCfgFile = outputDir + "/" + domainRunCfgFilename; + std::ofstream domainRunFILE(domainRunCfgFile); // add runs to files if (writeCF) { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { - domainRUNS << "--input_speed " << tree->wind->windTable->speed[i]->value() << "\n"; - domainRUNS << "--input_direction " << tree->wind->windTable->dir[i]->value() << "\n"; - domainRUNS << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; - domainRUNS << "--month " << tree->wind->windTable->date[i]->date().month() << "\n"; - domainRUNS << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; - domainRUNS << "--hour " << tree->wind->windTable->time[i]->time().hour() << "\n"; - domainRUNS << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; - domainRUNS << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; - domainRUNS << "--uni_cloud_cover " << tree->wind->windTable->cloudCover[i]->value() << "\n"; - domainRUNS << "--cloud_cover_units percent" << "\n" ; + domainRunFILE << "--input_speed " << tree->wind->windTable->speed[i]->value() << "\n"; + domainRunFILE << "--input_direction " << tree->wind->windTable->dir[i]->value() << "\n"; + domainRunFILE << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; + domainRunFILE << "--month " << tree->wind->windTable->date[i]->date().month() << "\n"; + domainRunFILE << "--day " << tree->wind->windTable->date[i]->date().day() << "\n"; + domainRunFILE << "--hour " << tree->wind->windTable->time[i]->time().hour() << "\n"; + domainRunFILE << "--minute " << tree->wind->windTable->time[i]->time().minute() << "\n"; + domainRunFILE << "--uni_air_temp " << tree->wind->windTable->airTemp[i]->value() << "\n"; + domainRunFILE << "--uni_cloud_cover " << tree->wind->windTable->cloudCover[i]->value() << "\n"; + domainRunFILE << "--cloud_cover_units percent" << "\n"; } } @@ -2893,14 +2903,14 @@ int mainWindow::solve() { //get speed if (writeCF) { - outFile << "--input_speed " << std::to_string(tree->wind->windTable->speed[i]->value()) << "\n"; + mainCaseCfgFILE << "--input_speed " << std::to_string(tree->wind->windTable->speed[i]->value()) << "\n"; } army->setInputSpeed( i, tree->wind->windTable->speed[i]->value(), inputSpeedUnits); //get direction if (writeCF) { - outFile << "--input_direction " << std::to_string(tree->wind->windTable->dir[i]->value()) << "\n"; + mainCaseCfgFILE << "--input_direction " << std::to_string(tree->wind->windTable->dir[i]->value()) << "\n"; } army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); @@ -2992,18 +3002,18 @@ int mainWindow::solve() { if(ninjafoamMeshChoice == WindNinjaInputs::coarse) { - outFile << "--mesh_count 25000\n"; + mainCaseCfgFILE << "--mesh_count 25000\n"; } else if(meshChoice == WindNinjaInputs::medium) { - outFile << "--mesh_count 50000\n"; + mainCaseCfgFILE << "--mesh_count 50000\n"; } else if(meshChoice == WindNinjaInputs::fine) { - outFile << "--mesh_count 100000\n"; + mainCaseCfgFILE << "--mesh_count 100000\n"; } } army->setNumberOfIterations( i, 300); if (writeCF) { - outFile << "--number_of_iterations 300\n"; + mainCaseCfgFILE << "--number_of_iterations 300\n"; } } else @@ -3053,27 +3063,29 @@ int mainWindow::solve() army->setNinjaComNumRuns( i, nRuns ); //add different input to config - domainRUNS.close(); - std::string domainaveragepath = "DomainAverage/run" + std::to_string(i) + ".cfg"; + domainRunFILE.close(); if (writeCF) { if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { - casefile.addFileToZip(zipFilePath, domainaveragepath, domaininputpath ); + std::string domainRunZipPathFile = "DomainAverageInitialization/" + domainRunCfgFilename; + casefile.addFileToZip(zipFile, domainRunZipPathFile, domainRunCfgFile ); } } - VSIUnlink( domaininputpath.c_str() ); + VSIUnlink( domainRunCfgFile.c_str() ); } // for(int i = 0;i < army->getSize(); i++) //set Casefile Directory and Input if (writeCF) { - outFile.close(); - casefile.addFileToZip(zipFilePath, getfileName, inputFileName.toStdString()); - casefile.addFileToZip(zipFilePath, "config.cfg", inputpath); - VSIUnlink( inputpath.c_str() ); - VSIUnlink( stationCSVFILEPATH.c_str() ); + mainCaseCfgFILE.close(); + std::string demZipPathFile = "/" + demFilename; + casefile.addFileToZip(zipFile, demZipPathFile, demFile); + std::string mainCaseCfgZipPathFile = "/" + mainCaseCfgFilename; + casefile.addFileToZip(zipFile, mainCaseCfgZipPathFile, mainCaseCfgFile); + VSIUnlink( mainCaseCfgFile.c_str() ); + VSIUnlink( selectedStationsFile.c_str() ); } army->set_writeFarsiteAtmFile( writeAtm && writeFb ); @@ -3851,7 +3863,7 @@ int mainWindow::checkShapeItem() else { tree->shapeItem->setIcon(0, tree->cross); - tree->shapeItem->setToolTip(0, "Cannot read input file") ; + tree->shapeItem->setToolTip(0, "Cannot read input file"); status = red; } } @@ -3895,7 +3907,7 @@ int mainWindow::checkPdfItem() else { tree->pdfItem->setIcon(0, tree->cross); - tree->pdfItem->setToolTip(0, "Cannot read input file") ; + tree->pdfItem->setToolTip(0, "Cannot read input file"); status = red; } } @@ -3922,7 +3934,7 @@ int mainWindow::checkVtkItem() else { tree->vtkItem->setIcon(0, tree->cross); - tree->vtkItem->setToolTip(0, "Cannot read input file") ; + tree->vtkItem->setToolTip(0, "Cannot read input file"); status = red; } } diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 13247cef..b2c1667c 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -50,19 +50,19 @@ void CaseFile::renameCaseZipFile(std::string newCaseZipFile) } -void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& withinZipPathedFilename, const std::string& fileToAdd) +void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& withinZipPathedFilename, const std::string& fileToAdd) { std::lock_guard lock(zipMutex); // for multithreading issue try { - bool doesZipExist = CPLCheckForFile(zipFilePath.c_str(), NULL); + bool doesZipExist = CPLCheckForFile(caseZippFile.c_str(), NULL); if (doesZipExist) { - std::ifstream infile(zipFilePath); + std::ifstream infile(caseZippFile); if (!infile.good()) { - CPLDebug("ZIP", "ZIP file does not exist: %s", zipFilePath.c_str()); + CPLDebug("ZIP", "ZIP file does not exist: %s", caseZippFile.c_str()); return; } } @@ -70,15 +70,15 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& w zipFile zip; if (!doesZipExist) { - zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_CREATE); + zip = cpl_zipOpen(caseZippFile.c_str(), APPEND_STATUS_CREATE); } else { - zip = cpl_zipOpen(zipFilePath.c_str(), APPEND_STATUS_ADDINZIP); + zip = cpl_zipOpen(caseZippFile.c_str(), APPEND_STATUS_ADDINZIP); } if (zip == NULL) { - CPLDebug("ZIP", "Could not open ZIP: %s", zipFilePath.c_str()); + CPLDebug("ZIP", "Could not open ZIP: %s", caseZippFile.c_str()); return; } @@ -134,7 +134,7 @@ void CaseFile::addFileToZip(const std::string& zipFilePath, const std::string& w if (cpl_zipClose(zip, nullptr) != ZIP_OK) { - CPLDebug("ZIP", "Error closing ZIP file: %s", zipFilePath.c_str()); + CPLDebug("ZIP", "Error closing ZIP file: %s", caseZippFile.c_str()); } } catch (const std::exception& e) diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 2662d6a9..2636e250 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -73,7 +73,7 @@ class CaseFile void renameCaseZipFile(std::string newCaseZipFile); - void addFileToZip(const std::string& zipFilePath, const std::string& withinZipPathedFilename, const std::string& fileToAdd); + void addFileToZip(const std::string& caseZippFile, const std::string& withinZipPathedFilename, const std::string& fileToAdd); std::string parse(const std::string& type, const std::string& path); diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 4f1716a2..5d9c63c4 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -462,24 +462,25 @@ int windNinjaCLI(int argc, char* argv[]) CaseFile casefile; if (vm["write_casefile"].as() == true) { - std::string getdir = vm.count("output_path") ? vm["output_path"].as().c_str() : ""; - std::cout << "getdir = \"" << getdir << "\"" << std::endl; + std::string outputDir = vm.count("output_path") ? vm["output_path"].as().c_str() : ""; + std::cout << "outputDir = \"" << outputDir << "\"" << std::endl; if( vm.count("output_path") ) { - getdir = vm["output_path"].as(); - } else // if (getdir == "") + outputDir = vm["output_path"].as(); + } else // if (outputDir == "") { // hrm, should work, but it isn't ideal. searches for "customOutputPath" in ninjafoam.cpp and ninja.cpp show // that this is correct to keep paths all the same EXCEPT for with weather model initialization, which uses // input.forecastFilename instead unless it is not set as an input, THEN it uses the dem file // it is not an easy thing to make sure we have forecastFilename here in the code the same way as later in the code - getdir = casefile.parse( "directory", vm["elevation_file"].as()); + outputDir = casefile.parse( "directory", vm["elevation_file"].as()); } - std::cout << "getdir = \"" << getdir << "\"" << std::endl; - std::string inputpath = getdir + "/config.cfg"; + std::cout << "outputDir = \"" << outputDir << "\"" << std::endl; + std::string mainCaseCfgFilename = "config.cfg"; + std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; - std::ofstream outFile(inputpath); - if (!outFile) + std::ofstream mainCaseCfgFILE(mainCaseCfgFile); + if (!mainCaseCfgFILE) { cerr << "Error: Could not open the file for writing!" << endl; return; @@ -490,66 +491,82 @@ int windNinjaCLI(int argc, char* argv[]) const std::string& option_name = pair.first; const po::variable_value& option_value = pair.second; - outFile << "--" << option_name << " "; + mainCaseCfgFILE << "--" << option_name << " "; try { - if (option_value.value().type() == typeid(int)) { - outFile << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(bool)) { - outFile << std::boolalpha << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(std::string)) { - outFile << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(double)) { - outFile << option_value.as() << std::endl; - } else if (option_value.value().type() == typeid(std::vector)) { + if (option_value.value().type() == typeid(int)) + { + mainCaseCfgFILE << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(bool)) + { + mainCaseCfgFILE << std::boolalpha << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(std::string)) + { + mainCaseCfgFILE << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(double)) + { + mainCaseCfgFILE << option_value.as() << std::endl; + } else if (option_value.value().type() == typeid(std::vector)) + { const auto& vec = option_value.as>(); - for (const auto& str : vec) { - outFile << str << " "; + for (const auto& str : vec) + { + mainCaseCfgFILE << str << " "; } - outFile << std::endl; - } else { - outFile << "Unknown type" << std::endl; + mainCaseCfgFILE << std::endl; + } else + { + mainCaseCfgFILE << "Unknown type" << std::endl; } - } catch (const boost::bad_any_cast& e) { - outFile << "Bad cast: " << e.what() << std::endl; + } catch (const boost::bad_any_cast& e) + { + mainCaseCfgFILE << "Bad cast: " << e.what() << std::endl; } } - std::string getfileName = casefile.parse("file", vm["elevation_file"].as()); + std::string demFile = vm["elevation_file"].as(); + std::string demFilename = casefile.parse("file", demFile); - std::string getconfigname = casefile.parse("file", vm["config_file"].as()); + std::string inputCfgFile = vm["config_file"].as(); + std::string inputCfgFilename = casefile.parse("file", inputCfgFile); - std::string zipFilePath = getdir + "/tmp.ninja"; + std::string zipFile = outputDir + "/tmp.ninja"; casefile.setIsZipOpen(true); - casefile.setCaseZipFile(zipFilePath); + casefile.setCaseZipFile(zipFile); // This flush is actually optional because close() will flush automatically - outFile.flush(); - outFile.close(); + mainCaseCfgFILE.flush(); + mainCaseCfgFILE.close(); + - casefile.addFileToZip(zipFilePath, getconfigname, vm["config_file"].as()); - casefile.addFileToZip(zipFilePath, getfileName, vm["elevation_file"].as()); - casefile.addFileToZip(zipFilePath, "config.cfg", inputpath); - VSIUnlink( inputpath.c_str() ); + std::string inputCfgZipPathFile = "/" + inputCfgFilename; + casefile.addFileToZip(zipFile, inputCfgZipPathFile, inputCfgFile); + std::string demZipPathFile = "/" + demFilename; + casefile.addFileToZip(zipFile, demZipPathFile, demFile); + std::string mainCaseCfgZipPathFile = "/" + mainCaseCfgFilename; + casefile.addFileToZip(zipFile, mainCaseCfgZipPathFile, mainCaseCfgFile); + VSIUnlink( mainCaseCfgFile.c_str() ); if (vm.count("forecast_filename")) { - std::string getweatherFileName = "weatherfile/" + casefile.parse("file", vm["forecast_filename"].as()); - casefile.addFileToZip(zipFilePath, getweatherFileName, vm["forecast_filename"].as()); + std::string weatherFile = vm["forecast_filename"].as(); + std::string weatherFilename = casefile.parse("file", weatherFile); + std::string weatherZipPathFile = "WxModelInitialization/" + weatherFilename; + casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); } if (vm.count("wx_station_filename")) { - std::vector tokens = split(vm["wx_station_filename"].as(), "/"); - std::string getpointFileName = casefile.parse("file", vm["wx_station_filename"].as()); - + std::string pointFile = vm["wx_station_filename"].as(); + std::vector tokens = split(pointFile, "/"); + std::string pointFilename = casefile.parse("file", pointFile); if (tokens.size() >= 2) { std::string secondToLastToken = tokens[tokens.size()-2]; if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - getpointFileName = secondToLastToken + "/" + tokens[tokens.size() - 1]; + pointFilename = secondToLastToken + "/" + tokens[tokens.size() - 1]; } } - - casefile.addFileToZip(zipFilePath, getpointFileName, vm["wx_station_filename"].as()); + std::string pointZipPathFile = "PointInitialization/" + pointFilename; + casefile.addFileToZip(zipFile, pointZipPathFile, pointFile); } } diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 24f621fc..67e7583f 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2822,9 +2822,9 @@ void ninja::writeOutputFiles() std::string vtkWriteFormat = "binary";//"binary";//"ascii"; volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string normfile = casefile->parse("file", input.volVTKFile); + std::string volVtkFilename = casefile->parse("file", input.volVTKFile); std::string directoryofVTK = casefile->parse("directory", input.volVTKFile); - std::string volVtkSurfFilename = casefile->parse("file", input.volVTKFile).substr(0, casefile->parse("file", input.volVTKFile).length() - 4) + "_surf" + casefile->parse("file", input.volVTKFile).substr(casefile->parse("file", input.volVTKFile).length() - 4, casefile->parse("file", input.volVTKFile).length()); + std::string volVtkSurfFilename = volVtkFilename.substr(0, volVtkFilename.length() - 4) + "_surf.vtk"; std::string volVtkSurfFile = directoryofVTK + "/" + volVtkSurfFilename; if( casefile->getIsZipOpen() ) { @@ -2840,9 +2840,11 @@ void ninja::writeOutputFiles() timestr = converttimetostd(input.ninjaTime); } - std::string zipFilePath = casefile->getCaseZipFile(); - casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + normfile, input.volVTKFile); - casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + volVtkSurfFilename, volVtkSurfFile); + std::string zipFile = casefile->getCaseZipFile(); + std::string volVtkZipPathFile = "/" + timestr + "/" + volVtkFilename; + casefile->addFileToZip(zipFile, volVtkZipPathFile, input.volVTKFile); + std::string volVtkSurfZipPathFile = "/" + timestr + "/" + volVtkSurfFilename; + casefile->addFileToZip(zipFile, volVtkSurfZipPathFile, volVtkSurfFile); } if( input.volVTKOutFlag == false ) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 6a0c0c01..20bb6b7c 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2689,7 +2689,7 @@ void NinjaFoam::writeMassMeshVtkOutput() fillEmptyProbeVals( massMesh.ZORD, input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, u, v, w ); - std::string massMeshVtkFilename = CPLFormFilename(pszFoamPath, "massMesh", "vtk"); + std::string massMeshVtkFile = CPLFormFilename(pszFoamPath, "massMesh", "vtk"); try { CPLDebug("NINJAFOAM", "writing vtk file"); bool vtk_out_as_utm = false; @@ -2699,11 +2699,11 @@ void NinjaFoam::writeMassMeshVtkOutput() } // can pick between "ascii" and "binary" format for the vtk write format std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; - volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFilename, vtkWriteFormat, vtk_out_as_utm); + volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFile, vtkWriteFormat, vtk_out_as_utm); - std::string normfile = casefile->parse("file", massMeshVtkFilename); - std::string directoryofVTK = casefile->parse("directory", massMeshVtkFilename); - std::string massMeshVtkSurfFilename = casefile->parse("file", massMeshVtkFilename).substr(0, casefile->parse("file", massMeshVtkFilename).length() - 4) + "_surf" + casefile->parse("file", massMeshVtkFilename).substr(casefile->parse("file", massMeshVtkFilename).length() - 4, casefile->parse("file", massMeshVtkFilename).length()); + std::string massMeshVtkFilename = casefile->parse("file", massMeshVtkFile); + std::string directoryofVTK = casefile->parse("directory", massMeshVtkFile); + std::string massMeshVtkSurfFilename = massMeshVtkFilename.substr(0, massMeshVtkFilename.length() - 4) + "_surf.vtk"; std::string massMeshVtkSurfFile = directoryofVTK + "/" + massMeshVtkSurfFilename; if( casefile->getIsZipOpen() ) { @@ -2719,14 +2719,16 @@ void NinjaFoam::writeMassMeshVtkOutput() timestr = converttimetostd(input.ninjaTime); } - std::string zipFilePath = casefile->getCaseZipFile(); - casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + normfile, massMeshVtkFilename); - casefile->addFileToZip(zipFilePath, "/" + timestr + "/" + massMeshVtkSurfFilename, massMeshVtkSurfFile); + std::string zipFile = casefile->getCaseZipFile(); + std::string massMeshVtkZipPathFile = "/" + timestr + "/" + massMeshVtkFilename; + casefile->addFileToZip(zipFile, massMeshVtkZipPathFile, massMeshVtkFile); + std::string massMeshVtkSurfZipPathFile = "/" + timestr + "/" + massMeshVtkSurfFilename; + casefile->addFileToZip(zipFile, massMeshVtkSurfZipPathFile, massMeshVtkSurfFile); } if( writeMassMeshVtk == false ) { - VSIUnlink( massMeshVtkFilename.c_str() ); + VSIUnlink( massMeshVtkFile.c_str() ); VSIUnlink( massMeshVtkSurfFile.c_str() ); } From 343043359e2ae350487a238db04099120dbc24ff Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 24 Mar 2025 15:04:54 -0600 Subject: [PATCH 23/35] 2nd cleanup attempt of casefile stuff continued, for issue #7 rearranged some of the inputs to casefile in mainWindow.cpp and cli.cpp, including the way ofstreams were being opened and used. Needed ofstreams to stay in scope only opening when required, instead of always opening. Similar updates to the locations in the code for file deletions, only open files when needed and if deletion is required, delete right after closing. Cleanup of the error code in mainWindow.cpp as well, have to use qt forms instead of throw in the gui first attempt at getting the proper full list of wxModel times, when the user selects 0 times and so the code runs using all wxModel times. Still some todo/issues with this method dropped some unused variables, functions, and dependencies in casefile as well --- src/gui/mainWindow.cpp | 146 +++++++++++++++++++++++++++-------------- src/ninja/casefile.cpp | 44 ------------- src/ninja/casefile.h | 31 +-------- src/ninja/cli.cpp | 29 ++++---- 4 files changed, 111 insertions(+), 139 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 426733ae..bd2cbd5c 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1659,51 +1659,51 @@ int mainWindow::solve() { std::string outputDir = tree->solve->outputDirectory().toStdString(); - if( outputDir == "" ) { - // This should never happen, so if it does, fix it. - throw( "no output directory specified in solve page" ); + if( outputDir == "" ) + { + // This should never happen, so if it does, fix it. + QMessageBox::critical(this,tr("Failure."), + "no output directory specified in solve page", + QMessageBox::Ok | QMessageBox::Default); + disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); + progressDialog->setValue( 0 ); + progressDialog->cancel(); + progressDialog->hide(); + disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); + setCursor(Qt::ArrowCursor); //Restart everything + return false; } - std::cout << "output_path = \"" << outputDir << "\"" << std::endl; bool writeCF = tree->solve->CaseFileBox->isChecked(); CaseFile casefile; - std::string mainCaseCfgFilename = "config.cfg"; - std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; - - std::string demFilename = casefile.parse("file", demFile); - - std::string selectedStationsFilename = "selected_stations.csv"; - std::string selectedStationsFile = outputDir + "/" + selectedStationsFilename; - std::string zipFile = outputDir + "/tmp.ninja"; - casefile.setIsZipOpen(true); - casefile.setCaseZipFile(zipFile); - - std::ofstream mainCaseCfgFILE(mainCaseCfgFile); - - std::ofstream selectedStationsFILE(selectedStationsFile); - - if (!mainCaseCfgFILE) { - std::cerr << "Error: Could not open the file for writing!" << std::endl; - return 1; - } - - if (!selectedStationsFILE) { - std::cerr << "Error: Could not open the file for writing!" << std::endl; - return 1; - } + std::string mainCaseCfgFilename = "config.cfg"; + std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; - if (!writeCF) { - mainCaseCfgFILE.close(); - selectedStationsFILE.close(); + std::ofstream mainCaseCfgFILE; - casefile.setIsZipOpen(false); - VSIUnlink( mainCaseCfgFile.c_str() ); - VSIUnlink( selectedStationsFile.c_str() ); + if (writeCF) { + casefile.setIsZipOpen(true); + casefile.setCaseZipFile(zipFile); + mainCaseCfgFILE.open(mainCaseCfgFile); + //if (!mainCaseCfgFILE.is_open()) // useful for debugging + if (!mainCaseCfgFILE) + { + QMessageBox::critical(this,tr("Failure."), + "Could not open the casefile " + QString(mainCaseCfgFile.c_str()) + " file for writing!", + QMessageBox::Ok | QMessageBox::Default); + disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); + progressDialog->setValue( 0 ); + progressDialog->cancel(); + progressDialog->hide(); + disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); + setCursor(Qt::ArrowCursor); //Restart everything + return false; + } } @@ -2450,6 +2450,23 @@ int mainWindow::solve() } } // setup list of actually used/selected stations + std::string selectedStationsFilename = "selected_stations.csv"; + std::string selectedStationsFile = outputDir + "/" + selectedStationsFilename; + std::ofstream selectedStationsFILE(selectedStationsFile); + if (!selectedStationsFILE) + { + QMessageBox::critical(this,tr("Failure."), + "Could not open the casefile " + QString(selectedStationsFile.c_str()) + " file for writing!", + QMessageBox::Ok | QMessageBox::Default); + disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); + progressDialog->setValue( 0 ); + progressDialog->cancel(); + progressDialog->hide(); + disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); + setCursor(Qt::ArrowCursor); //Restart everything + delete army; + return false; + } for (std::string & pointFile : pointFileList) { std::vector tokens = split(pointFile, "/"); @@ -2467,6 +2484,7 @@ int mainWindow::solve() selectedStationsFILE.close(); std::string selectedStationsZipPathFile = "PointInitialization/" + selectedStationsFilename; casefile.addFileToZip(zipFile, selectedStationsZipPathFile, selectedStationsFile); + VSIUnlink( selectedStationsFile.c_str() ); } // if (writeCF) @@ -2727,7 +2745,6 @@ int mainWindow::solve() std::vector times = tree->weather->timeList(); /* This can throw a badForecastFile */ - std::cout << "weather times.size() = " << times.size() << std::endl; if (writeCF && times.size() > 0) { std::vector stringTimes; @@ -2800,26 +2817,56 @@ int mainWindow::solve() //get times for casefile if no times are clicked by user if (writeCF && times.size() == 0) { - // TODO: casefile.setWxTime() for this instance needs to be called somewhere, currently casefile.getWxTime() just returns an empty list, - // yet, if the user purposefully unselects all times to select no input time, the code runs ALL the times in the forecast - // even better, replace casefile.setWxTime() and casefile.getWxTime() with a call to get the full weather forecast time list from some gui file somewhere - // started this, found that the list of times is already set and grabbable, but need to convert it from a QStringList into boost local_date_time objects + // this occurs if the user purposefully unselects all times to select no input time, while tree->weather->timeList() returns a list of 0 times, + // ninjaArmy replaces the empty times list with ALL the times in the forecast, the code runs ALL the weather forecast file times. + // Fortunately, it looks like tree->weather->timeModel->stringList() returns this list of times + // however, the list needs processed into boost local_date_time objects + // TODO: nvm, looks like the times returned from tree->weather->timeModel->stringList() are missing the year and date information required for conversions + // probably need to just setup a separate data list to get from weatherModel.h, or just replicate how ninjaArmy does it directly from the weatherFile. QStringList QString_wxTimesList = tree->weather->timeModel->stringList(); - std::cout << "QString_wxTimesList.size() = " << QString_wxTimesList.size() << std::endl; - std::vector wxtimesfromcasefile = casefile.getWxTimes(); std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - for (const auto& time : wxtimesfromcasefile) + for (const auto& QStringTime : QString_wxTimesList) { - // Convert local_date_time to ptime using the UTC time zone + // convert the QStringTime into a std::string + std::string sTime = QStringTime.toStdString(); + stringTimes.push_back(sTime); + + /*// convert the QStringTime into QDateTime + QString qTimeFormat = "yyyy-MM-ddTHH:mm:ssZ"; + QDateTime qDateTime = QDateTime::fromString(QStringTime,qTimeFormat); + qDateTime.setTimeSpec(Qt::UTC); //Set the Time to UTC + + blt::time_zone_ptr tz; // Initialize time zone + tz = globalTimeZoneDB.time_zone_from_region(timeZone.c_str()); // Get time zone from database + + // parse the QDateTime into date and time parts + int year = qDateTime.date().year(); + int month = qDateTime.date().month(); + int day = qDateTime.date().day(); + int hour = qDateTime.time().hour(); + int minute = qDateTime.time().minute(); + int sec = qDateTime.time().second(); + + // make intermediate start and stop dates for generating ptime objects + bg::date date(year,month,day); + bpt::time_duration duration(hour,minute,sec,0); + + // this time is UTC time + bpt::ptime ptime(date,duration); + + // this constructor generates local times from UTC times + blt::local_date_time time( ptime, tz );*/ + + /*// Convert local_date_time to ptime using the UTC time zone // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); - stringTimes.push_back(isoString); + stringTimes.push_back(isoString);*/ } std::string outstr; @@ -2853,14 +2900,15 @@ int mainWindow::solve() army->setCaseFilePtr( i, casefile ); + // add runs to files std::string domainRunCfgFilename = "run" + std::to_string(i) + "-DomainAverage.cfg"; std::string domainRunCfgFile = outputDir + "/" + domainRunCfgFilename; - std::ofstream domainRunFILE(domainRunCfgFile); - // add runs to files + std::ofstream domainRunFILE; if (writeCF) { if( initMethod == WindNinjaInputs::domainAverageInitializationFlag ) { + domainRunFILE.open(domainRunCfgFile); domainRunFILE << "--input_speed " << tree->wind->windTable->speed[i]->value() << "\n"; domainRunFILE << "--input_direction " << tree->wind->windTable->dir[i]->value() << "\n"; domainRunFILE << "--year " << tree->wind->windTable->date[i]->date().year() << "\n"; @@ -3063,16 +3111,16 @@ int mainWindow::solve() army->setNinjaComNumRuns( i, nRuns ); //add different input to config - domainRunFILE.close(); if (writeCF) { if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { + domainRunFILE.close(); std::string domainRunZipPathFile = "DomainAverageInitialization/" + domainRunCfgFilename; casefile.addFileToZip(zipFile, domainRunZipPathFile, domainRunCfgFile ); + VSIUnlink( domainRunCfgFile.c_str() ); } } - VSIUnlink( domainRunCfgFile.c_str() ); } // for(int i = 0;i < army->getSize(); i++) @@ -3080,12 +3128,12 @@ int mainWindow::solve() if (writeCF) { mainCaseCfgFILE.close(); + std::string demFilename = casefile.parse("file", demFile); std::string demZipPathFile = "/" + demFilename; casefile.addFileToZip(zipFile, demZipPathFile, demFile); std::string mainCaseCfgZipPathFile = "/" + mainCaseCfgFilename; casefile.addFileToZip(zipFile, mainCaseCfgZipPathFile, mainCaseCfgFile); VSIUnlink( mainCaseCfgFile.c_str() ); - VSIUnlink( selectedStationsFile.c_str() ); } army->set_writeFarsiteAtmFile( writeAtm && writeFb ); diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index b2c1667c..013adb45 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -7,9 +7,6 @@ CaseFile::CaseFile() { isZipOpen = false; caseZipFile = ""; - - downloadedfromdem = false; - elevsource = ""; } @@ -219,44 +216,3 @@ bool CaseFile::isVTKFile(const std::string& filePath) return false; } } - - -void CaseFile::setDownloadedFromDem(bool downloadedfromdemm) -{ - downloadedfromdem = downloadedfromdemm; -} - -bool CaseFile::getDownloadedFromDem() -{ - return downloadedfromdem; -} - -void CaseFile::setElevSource(std::string elevsourcee) -{ - elevsource = elevsourcee; -} - -std::string CaseFile::getElevSource() -{ - return elevsource; -} - -void CaseFile::setBoundingBox(std::vector boundingboxarrr) -{ - boundingboxarr = boundingboxarrr; -} - -std::vector CaseFile::getBoundingBox() -{ - return boundingboxarr; -} - -void CaseFile::setWxTimes(std::vector timeList) -{ - timesForWx = timeList; -} - -std::vector CaseFile::getWxTimes() -{ - return timesForWx; -} diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 2636e250..8848206a 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -30,21 +30,13 @@ #ifndef CASEFILE_H #define CASEFILE_H -#include #include -#include -#include "cpl_vsi.h" -#include "gdal.h" -#include +#include #include -#include -#include #include "cpl_minizip_zip.h" +#include #include #include -#include -#include -#include class CaseFile { @@ -54,12 +46,6 @@ class CaseFile bool isZipOpen; std::string caseZipFile; - bool downloadedfromdem; - std::string elevsource; - std::vector boundingboxarr; - - std::vector timesForWx; - public: CaseFile(); @@ -83,19 +69,6 @@ class CaseFile bool isCfgFile(const std::string& filePath); bool isVTKFile(const std::string& filePath); - - void setDownloadedFromDem(bool downloadedfromdemm); - bool getDownloadedFromDem(); - - void setElevSource(std::string elevsourcee); - std::string getElevSource(); - - void setBoundingBox(std::vector boundingboxarrr); - std::vector CaseFile::getBoundingBox(); - - void setWxTimes(std::vector timeList); - std::vector getWxTimes(); - }; #endif /* CASEFILE_H */ diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 5d9c63c4..233e0da5 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -463,7 +463,6 @@ int windNinjaCLI(int argc, char* argv[]) if (vm["write_casefile"].as() == true) { std::string outputDir = vm.count("output_path") ? vm["output_path"].as().c_str() : ""; - std::cout << "outputDir = \"" << outputDir << "\"" << std::endl; if( vm.count("output_path") ) { outputDir = vm["output_path"].as(); @@ -475,15 +474,20 @@ int windNinjaCLI(int argc, char* argv[]) // it is not an easy thing to make sure we have forecastFilename here in the code the same way as later in the code outputDir = casefile.parse( "directory", vm["elevation_file"].as()); } - std::cout << "outputDir = \"" << outputDir << "\"" << std::endl; + + std::string zipFile = outputDir + "/tmp.ninja"; + std::string mainCaseCfgFilename = "config.cfg"; std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; + casefile.setIsZipOpen(true); + casefile.setCaseZipFile(zipFile); + std::ofstream mainCaseCfgFILE(mainCaseCfgFile); if (!mainCaseCfgFILE) { - cerr << "Error: Could not open the file for writing!" << endl; - return; + std::cerr << "Error: Could not open the casefile " << mainCaseCfgFile << " file for writing!" << std::endl; + return 1; } for (const auto& pair : vm) @@ -523,25 +527,16 @@ int windNinjaCLI(int argc, char* argv[]) mainCaseCfgFILE << "Bad cast: " << e.what() << std::endl; } } - - std::string demFile = vm["elevation_file"].as(); - std::string demFilename = casefile.parse("file", demFile); - - std::string inputCfgFile = vm["config_file"].as(); - std::string inputCfgFilename = casefile.parse("file", inputCfgFile); - - std::string zipFile = outputDir + "/tmp.ninja"; - - casefile.setIsZipOpen(true); - casefile.setCaseZipFile(zipFile); - // This flush is actually optional because close() will flush automatically mainCaseCfgFILE.flush(); mainCaseCfgFILE.close(); - + std::string inputCfgFile = vm["config_file"].as(); + std::string inputCfgFilename = casefile.parse("file", inputCfgFile); std::string inputCfgZipPathFile = "/" + inputCfgFilename; casefile.addFileToZip(zipFile, inputCfgZipPathFile, inputCfgFile); + std::string demFile = vm["elevation_file"].as(); + std::string demFilename = casefile.parse("file", demFile); std::string demZipPathFile = "/" + demFilename; casefile.addFileToZip(zipFile, demZipPathFile, demFile); std::string mainCaseCfgZipPathFile = "/" + mainCaseCfgFilename; From 31afa5ec9d37e385082010fae8e279f48605f74c Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 24 Mar 2025 17:07:16 -0600 Subject: [PATCH 24/35] 2nd cleanup attempt of casefile stuff continued, for issue #7 moved split() and convertDateTimeToStd() from various places in the code to the casefile code itself. Also, replaced all instances of parse() with cross platform compatible CPLGetFilename(), CPLGetPath(). Also attempted to replace all path combining instances with "/" instances with CPLFormFilename() --- src/gui/mainWindow.cpp | 53 +++++++++++------------------- src/gui/mainWindow.h | 2 -- src/ninja/casefile.cpp | 71 +++++++++++------------------------------ src/ninja/casefile.h | 7 ++-- src/ninja/cli.cpp | 44 ++++++++----------------- src/ninja/cli.h | 2 -- src/ninja/ninja.cpp | 20 ++++-------- src/ninja/ninja.h | 2 -- src/ninja/ninjafoam.cpp | 12 +++---- 9 files changed, 64 insertions(+), 149 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index bd2cbd5c..cdd99d6c 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1679,10 +1679,10 @@ int mainWindow::solve() CaseFile casefile; - std::string zipFile = outputDir + "/tmp.ninja"; + std::string zipFile = CPLFormFilename(outputDir.c_str(), "tmp", "ninja"); std::string mainCaseCfgFilename = "config.cfg"; - std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; + std::string mainCaseCfgFile = CPLFormFilename(outputDir.c_str(), mainCaseCfgFilename.c_str(), ""); std::ofstream mainCaseCfgFILE; @@ -2432,14 +2432,14 @@ int mainWindow::solve() std::vector fullFileListPoint = tree->point->fullFileList; for (std::string & pointFile : fullFileListPoint) { - std::vector tokens = split(pointFile, "/"); + std::vector tokens = casefile.split(pointFile, "/"); if (tokens.size() >= 2) { std::string secondToLastToken = tokens[tokens.size()-2]; std::string pointFilename1 = tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1]; std::string pointFilename2 = tokens[tokens.size()-1]; - std::string pointZipPathFile1 = "PointInitialization/" + pointFilename1; - std::string pointZipPathFile2 = "PointInitialization/" + pointFilename2; + std::string pointZipPathFile1 = CPLFormFilename("PointInitialization", pointFilename1.c_str(), ""); + std::string pointZipPathFile2 = CPLFormFilename("PointInitialization", pointFilename2.c_str(), ""); if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { casefile.addFileToZip(zipFile, pointZipPathFile1, pointFile); @@ -2451,7 +2451,7 @@ int mainWindow::solve() } // setup list of actually used/selected stations std::string selectedStationsFilename = "selected_stations.csv"; - std::string selectedStationsFile = outputDir + "/" + selectedStationsFilename; + std::string selectedStationsFile = CPLFormFilename(outputDir.c_str(), selectedStationsFilename.c_str(), ""); std::ofstream selectedStationsFILE(selectedStationsFile); if (!selectedStationsFILE) { @@ -2469,8 +2469,8 @@ int mainWindow::solve() } for (std::string & pointFile : pointFileList) { - std::vector tokens = split(pointFile, "/"); - std::string pointFilename = casefile.parse("file", pointFile); + std::vector tokens = casefile.split(pointFile, "/"); + std::string pointFilename = CPLGetFilename( pointFile.c_str() ); if (tokens.size() >= 2) { std::string secondToLastToken = tokens[tokens.size()-2]; @@ -2482,7 +2482,7 @@ int mainWindow::solve() selectedStationsFILE << pointFilename << "\n"; } selectedStationsFILE.close(); - std::string selectedStationsZipPathFile = "PointInitialization/" + selectedStationsFilename; + std::string selectedStationsZipPathFile = CPLFormFilename("PointInitialization", selectedStationsFilename.c_str(), ""); casefile.addFileToZip(zipFile, selectedStationsZipPathFile, selectedStationsFile); VSIUnlink( selectedStationsFile.c_str() ); @@ -2773,8 +2773,8 @@ int mainWindow::solve() mainCaseCfgFILE << "--forecast_times " << outstr << "\n"; mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; - std::string weatherFilename = casefile.parse("file", weatherFile); - std::string weatherZipPathFile = "WxModelInitialization/" + weatherFilename; + std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); + std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); } // if (writeCF && times.size() > 0) @@ -2881,8 +2881,8 @@ int mainWindow::solve() mainCaseCfgFILE << "--forecast_times " << outstr << "\n"; mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; - std::string weatherFilename = casefile.parse("file", weatherFile); - std::string weatherZipPathFile = "WxModelInitialization/" + weatherFilename; + std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); + std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); } // if (writeCF && times.size() == 0) @@ -2902,7 +2902,7 @@ int mainWindow::solve() // add runs to files std::string domainRunCfgFilename = "run" + std::to_string(i) + "-DomainAverage.cfg"; - std::string domainRunCfgFile = outputDir + "/" + domainRunCfgFilename; + std::string domainRunCfgFile = CPLFormFilename(outputDir.c_str(), domainRunCfgFilename.c_str(), ""); std::ofstream domainRunFILE; if (writeCF) { @@ -3116,7 +3116,7 @@ int mainWindow::solve() if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { domainRunFILE.close(); - std::string domainRunZipPathFile = "DomainAverageInitialization/" + domainRunCfgFilename; + std::string domainRunZipPathFile = CPLFormFilename("DomainAverageInitialization", domainRunCfgFilename.c_str(), ""); casefile.addFileToZip(zipFile, domainRunZipPathFile, domainRunCfgFile ); VSIUnlink( domainRunCfgFile.c_str() ); } @@ -3128,11 +3128,9 @@ int mainWindow::solve() if (writeCF) { mainCaseCfgFILE.close(); - std::string demFilename = casefile.parse("file", demFile); - std::string demZipPathFile = "/" + demFilename; - casefile.addFileToZip(zipFile, demZipPathFile, demFile); - std::string mainCaseCfgZipPathFile = "/" + mainCaseCfgFilename; - casefile.addFileToZip(zipFile, mainCaseCfgZipPathFile, mainCaseCfgFile); + std::string demFilename = CPLGetFilename( demFile.c_str() ); + casefile.addFileToZip(zipFile, demFilename, demFile); + casefile.addFileToZip(zipFile, mainCaseCfgFilename, mainCaseCfgFile); VSIUnlink( mainCaseCfgFile.c_str() ); } @@ -4200,21 +4198,6 @@ QString mainWindow::checkForNoData( QString inputFile ) return newFile; } -// string splitter, splits an input string into pieces separated by an input delimiter -// used for point initialization in casefile -std::vector mainWindow::split(const std::string &s, const std::string &delimiter) { - std::vector tokens; - size_t start = 0; - size_t end = s.find(delimiter); - while (end != std::string::npos) { - tokens.push_back(s.substr(start, end - start)); - start = end + delimiter.length(); - end = s.find(delimiter, start); - } - tokens.push_back(s.substr(start, end)); - return tokens; -} - void mainWindow::enablePointDate(bool enable) { (void)enable; diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index 827edc94..b7ff7b13 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -291,8 +291,6 @@ class mainWindow : public QMainWindow void writeSettings(); QString checkForNoData( QString fileName ); - std::vector split(const std::string &s, const std::string &delimiter); - QVBoxLayout *mainLayout; QFileSystemWatcher fileWatcher; diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 013adb45..e1297415 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -33,7 +33,7 @@ std::string CaseFile::getCaseZipFile() // to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name void CaseFile::renameCaseZipFile(std::string newCaseZipFile) { - if (parse("file", caseZipFile) == "tmp.ninja") + if (strcmp( CPLGetFilename( caseZipFile.c_str() ), "tmp.ninja" ) == 0) { if (VSIRename(caseZipFile.c_str(), newCaseZipFile.c_str()) == 0) { @@ -146,37 +146,21 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& } -std::string CaseFile::parse(const std::string& type, const std::string& path) +// string splitter, splits an input string into pieces separated by an input delimiter +// used for point initialization in casefile +std::vector CaseFile::split(const std::string &s, const std::string &delimiter) { - size_t found = path.find_last_of("/"); - if (found != std::string::npos) + std::vector tokens; + size_t start = 0; + size_t end = s.find(delimiter); + while (end != std::string::npos) { - if (strcmp(type.c_str(), "directory") == 0) - { - return path.substr(0, found); - } else - { - if (strcmp(type.c_str(), "file") == 0) - { - return path.substr(found + 1); // Extract substring after the last '/' - } - } - } else - { - //std::cout << "couldn't parse" << std::endl; - //return ""; - return path; + tokens.push_back(s.substr(start, end - start)); + start = end + delimiter.length(); + end = s.find(delimiter, start); } -} - -std::string CaseFile::convertDateTime(const boost::local_time::local_date_time& ninjaTime) -{ - return ""; -} - -bool CaseFile::lookForDate(const std::string& date) -{ - return false; + tokens.push_back(s.substr(start, end)); + return tokens; } std::string CaseFile::getTime() @@ -191,28 +175,11 @@ std::string CaseFile::getTime() return oss.str(); } -bool CaseFile::isCfgFile(const std::string& filePath) +std::string CaseFile::convertDateTimeToStd(const boost::local_time::local_date_time& ninjaTime) { - const std::string extension = ".cfg"; - if (filePath.length() >= extension.length()) - { - std::string fileExtension = filePath.substr(filePath.length() - extension.length()); - return fileExtension == extension; - } else - { - return false; - } -} - -bool CaseFile::isVTKFile(const std::string& filePath) -{ - const std::string extension = ".vtk"; - if (filePath.length() >= extension.length()) - { - std::string fileExtension = filePath.substr(filePath.length() - extension.length()); - return fileExtension == extension; - } else - { - return false; - } + std::ostringstream ss; + ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); + ss << ninjaTime; + std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); + return result; } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 8848206a..2f5d1d25 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -62,12 +62,9 @@ class CaseFile void addFileToZip(const std::string& caseZippFile, const std::string& withinZipPathedFilename, const std::string& fileToAdd); - std::string parse(const std::string& type, const std::string& path); - std::string convertDateTime(const boost::local_time::local_date_time& ninjaTime); - bool lookForDate(const std::string& date); + std::vector split(const std::string &s, const std::string &delimiter); std::string getTime(); - bool isCfgFile(const std::string& filePath); - bool isVTKFile(const std::string& filePath); + std::string convertDateTimeToStd(const boost::local_time::local_date_time& ninjaTime); }; diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 233e0da5..f3a4e2e9 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -136,21 +136,6 @@ const std::string* get_checked_elevation_file(po::variables_map& vm) } } -// string splitter, splits an input string into pieces separated by an input delimiter -// used for point initialization in casefile -std::vector split(const std::string &s, const std::string &delimiter) { - std::vector tokens; - size_t start = 0; - size_t end = s.find(delimiter); - while (end != std::string::npos) { - tokens.push_back(s.substr(start, end - start)); - start = end + delimiter.length(); - end = s.find(delimiter, start); - } - tokens.push_back(s.substr(start, end)); - return tokens; -} - /** * Command line implementation (CLI) of WindNinja. Can be run using command line args or * from an input file. @@ -472,13 +457,13 @@ int windNinjaCLI(int argc, char* argv[]) // that this is correct to keep paths all the same EXCEPT for with weather model initialization, which uses // input.forecastFilename instead unless it is not set as an input, THEN it uses the dem file // it is not an easy thing to make sure we have forecastFilename here in the code the same way as later in the code - outputDir = casefile.parse( "directory", vm["elevation_file"].as()); + outputDir = CPLGetPath( vm["elevation_file"].as().c_str() ); } - std::string zipFile = outputDir + "/tmp.ninja"; + std::string zipFile = CPLFormFilename(outputDir.c_str(), "tmp", "ninja"); std::string mainCaseCfgFilename = "config.cfg"; - std::string mainCaseCfgFile = outputDir + "/" + mainCaseCfgFilename; + std::string mainCaseCfgFile = CPLFormFilename(outputDir.c_str(), mainCaseCfgFilename.c_str(), ""); casefile.setIsZipOpen(true); casefile.setCaseZipFile(zipFile); @@ -532,35 +517,32 @@ int windNinjaCLI(int argc, char* argv[]) mainCaseCfgFILE.close(); std::string inputCfgFile = vm["config_file"].as(); - std::string inputCfgFilename = casefile.parse("file", inputCfgFile); - std::string inputCfgZipPathFile = "/" + inputCfgFilename; - casefile.addFileToZip(zipFile, inputCfgZipPathFile, inputCfgFile); + std::string inputCfgFilename = CPLGetFilename( inputCfgFile.c_str() ); + casefile.addFileToZip(zipFile, inputCfgFilename, inputCfgFile); std::string demFile = vm["elevation_file"].as(); - std::string demFilename = casefile.parse("file", demFile); - std::string demZipPathFile = "/" + demFilename; - casefile.addFileToZip(zipFile, demZipPathFile, demFile); - std::string mainCaseCfgZipPathFile = "/" + mainCaseCfgFilename; - casefile.addFileToZip(zipFile, mainCaseCfgZipPathFile, mainCaseCfgFile); + std::string demFilename = CPLGetFilename( demFile.c_str() ); + casefile.addFileToZip(zipFile, demFilename, demFile); + casefile.addFileToZip(zipFile, mainCaseCfgFilename, mainCaseCfgFile); VSIUnlink( mainCaseCfgFile.c_str() ); if (vm.count("forecast_filename")) { std::string weatherFile = vm["forecast_filename"].as(); - std::string weatherFilename = casefile.parse("file", weatherFile); - std::string weatherZipPathFile = "WxModelInitialization/" + weatherFilename; + std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); + std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); } if (vm.count("wx_station_filename")) { std::string pointFile = vm["wx_station_filename"].as(); - std::vector tokens = split(pointFile, "/"); - std::string pointFilename = casefile.parse("file", pointFile); + std::vector tokens = casefile.split(pointFile, "/"); + std::string pointFilename = CPLGetFilename( pointFile.c_str() ); if (tokens.size() >= 2) { std::string secondToLastToken = tokens[tokens.size()-2]; if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { pointFilename = secondToLastToken + "/" + tokens[tokens.size() - 1]; } } - std::string pointZipPathFile = "PointInitialization/" + pointFilename; + std::string pointZipPathFile = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); casefile.addFileToZip(zipFile, pointZipPathFile, pointFile); } } diff --git a/src/ninja/cli.h b/src/ninja/cli.h index 6efc4a86..e58deaa6 100644 --- a/src/ninja/cli.h +++ b/src/ninja/cli.h @@ -65,8 +65,6 @@ pair at_option_parser(string const&s); const std::string* get_checked_elevation_file(po::variables_map& vm); -std::vector split(const std::string &s, const std::string &delimiter); - // this should be used instead of direct 'variables_map["key"].as()' calls since otherwise a single typo // in the key literal results in undefined behavior that can corrupt memory miles away. // Alternatively keys could be defined/used as constants to catch this at compile time diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 67e7583f..e1f64bb7 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2822,10 +2822,10 @@ void ninja::writeOutputFiles() std::string vtkWriteFormat = "binary";//"binary";//"ascii"; volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string volVtkFilename = casefile->parse("file", input.volVTKFile); - std::string directoryofVTK = casefile->parse("directory", input.volVTKFile); + std::string volVtkFilename = CPLGetFilename( input.volVTKFile.c_str() ); + std::string directoryofVTK = CPLGetPath( input.volVTKFile.c_str() ); std::string volVtkSurfFilename = volVtkFilename.substr(0, volVtkFilename.length() - 4) + "_surf.vtk"; - std::string volVtkSurfFile = directoryofVTK + "/" + volVtkSurfFilename; + std::string volVtkSurfFile = CPLFormFilename(directoryofVTK.c_str(), volVtkSurfFilename.c_str(), ""); if( casefile->getIsZipOpen() ) { casefile->renameCaseZipFile(casefilename); @@ -2837,13 +2837,13 @@ void ninja::writeOutputFiles() timestr = getlocaltime; } else { - timestr = converttimetostd(input.ninjaTime); + timestr = casefile->convertDateTimeToStd(input.ninjaTime); } std::string zipFile = casefile->getCaseZipFile(); - std::string volVtkZipPathFile = "/" + timestr + "/" + volVtkFilename; + std::string volVtkZipPathFile = CPLFormFilename(timestr.c_str(), volVtkFilename.c_str(), ""); casefile->addFileToZip(zipFile, volVtkZipPathFile, input.volVTKFile); - std::string volVtkSurfZipPathFile = "/" + timestr + "/" + volVtkSurfFilename; + std::string volVtkSurfZipPathFile = CPLFormFilename(timestr.c_str(), volVtkSurfFilename.c_str(), ""); casefile->addFileToZip(zipFile, volVtkSurfZipPathFile, volVtkSurfFile); } @@ -5316,14 +5316,6 @@ void ninja::dumpMemory() input.surface.deallocate(); } -std::string ninja::converttimetostd(const boost::local_time::local_date_time& ninjaTime) { - std::ostringstream ss; - ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); - ss << ninjaTime; - std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); - return result; -} - // derive a new pathname from the given one, swapping the path (if given) and optionally applying a regex replacement std::string derived_pathname (const char* pathname, const char* newpath, const char* pattern, const char* replacement) diff --git a/src/ninja/ninja.h b/src/ninja/ninja.h index ec1cb731..08f26789 100644 --- a/src/ninja/ninja.h +++ b/src/ninja/ninja.h @@ -366,8 +366,6 @@ class ninja void checkInputs(); void dumpMemory(); - std::string converttimetostd(const boost::local_time::local_date_time& ninjaTime); - WindNinjaInputs input; //The place where all inputs (except mesh) are stored. protected: diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 20bb6b7c..9978bdc3 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2701,10 +2701,10 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string vtkWriteFormat = "ascii";//"binary";//"ascii"; volVTK VTK(u, v, w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, massMeshVtkFile, vtkWriteFormat, vtk_out_as_utm); - std::string massMeshVtkFilename = casefile->parse("file", massMeshVtkFile); - std::string directoryofVTK = casefile->parse("directory", massMeshVtkFile); + std::string massMeshVtkFilename = CPLGetFilename( massMeshVtkFile.c_str() ); + std::string directoryofVTK = CPLGetPath( massMeshVtkFile.c_str() ); std::string massMeshVtkSurfFilename = massMeshVtkFilename.substr(0, massMeshVtkFilename.length() - 4) + "_surf.vtk"; - std::string massMeshVtkSurfFile = directoryofVTK + "/" + massMeshVtkSurfFilename; + std::string massMeshVtkSurfFile = CPLFormFilename(directoryofVTK.c_str(), massMeshVtkSurfFilename.c_str(), ""); if( casefile->getIsZipOpen() ) { casefile->renameCaseZipFile(casefilename); @@ -2716,13 +2716,13 @@ void NinjaFoam::writeMassMeshVtkOutput() timestr = getlocaltime; } else { - timestr = converttimetostd(input.ninjaTime); + timestr = casefile->convertDateTimeToStd(input.ninjaTime); } std::string zipFile = casefile->getCaseZipFile(); - std::string massMeshVtkZipPathFile = "/" + timestr + "/" + massMeshVtkFilename; + std::string massMeshVtkZipPathFile = CPLFormFilename(timestr.c_str(), massMeshVtkFilename.c_str(), ""); casefile->addFileToZip(zipFile, massMeshVtkZipPathFile, massMeshVtkFile); - std::string massMeshVtkSurfZipPathFile = "/" + timestr + "/" + massMeshVtkSurfFilename; + std::string massMeshVtkSurfZipPathFile = CPLFormFilename(timestr.c_str(), massMeshVtkSurfFilename.c_str(), ""); casefile->addFileToZip(zipFile, massMeshVtkSurfZipPathFile, massMeshVtkSurfFile); } From b2ce9b02e34b0a083d7bb0b927d1df337e98e379 Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 24 Mar 2025 19:36:17 -0600 Subject: [PATCH 25/35] 2nd cleanup attempt of casefile stuff, final wrapup, for issue #7 got rid of split() function instances, by using cross platform compatible CPLGetFilename(), CPLGetPath(), and CPLFormFilename() functions instead. So cleanup of the station casefile stuff got rid of zipFile as input to various functions, just use the set value within the class figured out how to get the times right for the weatherModelInitialization with times.size() = 0 case, just required adding a getFullTimesList() style function in weatherModel.cpp cleaned up time stuff, including a change to the time facet to drop instances of ":" chars, windows does NOT like filenames with such ":" chars. General cleanup of time methods, as well as an attempt at doing a bit of cleanup to the addFileToZip() function, especially changing out the warning/error messaging functions that were used final general cleanup, dropped a few last unused #include header dependencies --- src/gui/mainWindow.cpp | 84 +++++++++------------------------------- src/gui/mainWindow.h | 3 -- src/gui/weatherModel.cpp | 4 ++ src/gui/weatherModel.h | 1 + src/ninja/casefile.cpp | 64 ++++++++++++------------------ src/ninja/casefile.h | 8 +--- src/ninja/cli.cpp | 20 +++++----- src/ninja/ninja.cpp | 8 ++-- src/ninja/ninjafoam.cpp | 8 ++-- 9 files changed, 65 insertions(+), 135 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index cdd99d6c..b60db099 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -2432,22 +2432,14 @@ int mainWindow::solve() std::vector fullFileListPoint = tree->point->fullFileList; for (std::string & pointFile : fullFileListPoint) { - std::vector tokens = casefile.split(pointFile, "/"); - if (tokens.size() >= 2) + std::string pointFilename = CPLGetFilename( pointFile.c_str() ); + std::string pointPath = CPLGetPath( pointFile.c_str() ); + if (pointPath.find("WXSTATIONS-") != std::string::npos) { - std::string secondToLastToken = tokens[tokens.size()-2]; - std::string pointFilename1 = tokens[tokens.size()-2] + "/" + tokens[tokens.size()-1]; - std::string pointFilename2 = tokens[tokens.size()-1]; - std::string pointZipPathFile1 = CPLFormFilename("PointInitialization", pointFilename1.c_str(), ""); - std::string pointZipPathFile2 = CPLFormFilename("PointInitialization", pointFilename2.c_str(), ""); - if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) - { - casefile.addFileToZip(zipFile, pointZipPathFile1, pointFile); - } else - { - casefile.addFileToZip(zipFile, pointZipPathFile2, pointFile); - } + pointFilename = CPLFormFilename(CPLGetFilename(pointPath.c_str()), pointFilename.c_str(), ""); } + std::string pointZipPathFile = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); + casefile.addFileToZip(pointZipPathFile, pointFile); } // setup list of actually used/selected stations std::string selectedStationsFilename = "selected_stations.csv"; @@ -2469,21 +2461,17 @@ int mainWindow::solve() } for (std::string & pointFile : pointFileList) { - std::vector tokens = casefile.split(pointFile, "/"); std::string pointFilename = CPLGetFilename( pointFile.c_str() ); - if (tokens.size() >= 2) + std::string pointPath = CPLGetPath( pointFile.c_str() ); + if (pointPath.find("WXSTATIONS-") != std::string::npos) { - std::string secondToLastToken = tokens[tokens.size()-2]; - if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) - { - pointFilename = secondToLastToken + "/" + tokens[tokens.size() - 1]; - } + pointFilename = CPLFormFilename(CPLGetFilename(pointPath.c_str()), pointFilename.c_str(), ""); } selectedStationsFILE << pointFilename << "\n"; } selectedStationsFILE.close(); std::string selectedStationsZipPathFile = CPLFormFilename("PointInitialization", selectedStationsFilename.c_str(), ""); - casefile.addFileToZip(zipFile, selectedStationsZipPathFile, selectedStationsFile); + casefile.addFileToZip(selectedStationsZipPathFile, selectedStationsFile); VSIUnlink( selectedStationsFile.c_str() ); } // if (writeCF) @@ -2775,7 +2763,7 @@ int mainWindow::solve() mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); - casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); + casefile.addFileToZip(weatherZipPathFile, weatherFile); } // if (writeCF && times.size() > 0) try @@ -2819,54 +2807,20 @@ int mainWindow::solve() { // this occurs if the user purposefully unselects all times to select no input time, while tree->weather->timeList() returns a list of 0 times, // ninjaArmy replaces the empty times list with ALL the times in the forecast, the code runs ALL the weather forecast file times. - // Fortunately, it looks like tree->weather->timeModel->stringList() returns this list of times - // however, the list needs processed into boost local_date_time objects - // TODO: nvm, looks like the times returned from tree->weather->timeModel->stringList() are missing the year and date information required for conversions - // probably need to just setup a separate data list to get from weatherModel.h, or just replicate how ninjaArmy does it directly from the weatherFile. - QStringList QString_wxTimesList = tree->weather->timeModel->stringList(); + std::vector fullTimesList = tree->weather->getFullTimeList(); std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - for (const auto& QStringTime : QString_wxTimesList) + for (const auto& time : fullTimesList) { - // convert the QStringTime into a std::string - std::string sTime = QStringTime.toStdString(); - stringTimes.push_back(sTime); - - /*// convert the QStringTime into QDateTime - QString qTimeFormat = "yyyy-MM-ddTHH:mm:ssZ"; - QDateTime qDateTime = QDateTime::fromString(QStringTime,qTimeFormat); - qDateTime.setTimeSpec(Qt::UTC); //Set the Time to UTC - - blt::time_zone_ptr tz; // Initialize time zone - tz = globalTimeZoneDB.time_zone_from_region(timeZone.c_str()); // Get time zone from database - - // parse the QDateTime into date and time parts - int year = qDateTime.date().year(); - int month = qDateTime.date().month(); - int day = qDateTime.date().day(); - int hour = qDateTime.time().hour(); - int minute = qDateTime.time().minute(); - int sec = qDateTime.time().second(); - - // make intermediate start and stop dates for generating ptime objects - bg::date date(year,month,day); - bpt::time_duration duration(hour,minute,sec,0); - - // this time is UTC time - bpt::ptime ptime(date,duration); - - // this constructor generates local times from UTC times - blt::local_date_time time( ptime, tz );*/ - - /*// Convert local_date_time to ptime using the UTC time zone + // Convert local_date_time to ptime using the UTC time zone // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); - stringTimes.push_back(isoString);*/ + stringTimes.push_back(isoString); } std::string outstr; @@ -2883,7 +2837,7 @@ int mainWindow::solve() mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); - casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); + casefile.addFileToZip(weatherZipPathFile, weatherFile); } // if (writeCF && times.size() == 0) nRuns = army->getSize(); @@ -3117,7 +3071,7 @@ int mainWindow::solve() { domainRunFILE.close(); std::string domainRunZipPathFile = CPLFormFilename("DomainAverageInitialization", domainRunCfgFilename.c_str(), ""); - casefile.addFileToZip(zipFile, domainRunZipPathFile, domainRunCfgFile ); + casefile.addFileToZip(domainRunZipPathFile, domainRunCfgFile ); VSIUnlink( domainRunCfgFile.c_str() ); } } @@ -3129,8 +3083,8 @@ int mainWindow::solve() { mainCaseCfgFILE.close(); std::string demFilename = CPLGetFilename( demFile.c_str() ); - casefile.addFileToZip(zipFile, demFilename, demFile); - casefile.addFileToZip(zipFile, mainCaseCfgFilename, mainCaseCfgFile); + casefile.addFileToZip(demFilename, demFile); + casefile.addFileToZip(mainCaseCfgFilename, mainCaseCfgFile); VSIUnlink( mainCaseCfgFile.c_str() ); } diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index b7ff7b13..16434d5f 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -65,9 +65,6 @@ #include "ninjaArmy.h" #include "ninja_conv.h" -#include -#include - #include "setconfigdialog.h" class mainWindow : public QMainWindow diff --git a/src/gui/weatherModel.cpp b/src/gui/weatherModel.cpp index 906e8f46..ac84fc94 100644 --- a/src/gui/weatherModel.cpp +++ b/src/gui/weatherModel.cpp @@ -561,6 +561,10 @@ std::vector weatherModel::timeList() { return tl; } +std::vector weatherModel::getFullTimeList() { + return timelist; +} + void weatherModel::clearTimes() { timelist.clear(); timeModel->setStringList(QStringList()); diff --git a/src/gui/weatherModel.h b/src/gui/weatherModel.h index 13d468ac..512eb18d 100644 --- a/src/gui/weatherModel.h +++ b/src/gui/weatherModel.h @@ -136,6 +136,7 @@ class weatherModel : public QWidget QString tzString; std::vector timeList(); + std::vector getFullTimeList(); private: void loadModelComboBox(); diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index e1297415..d3e39dcc 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -2,14 +2,12 @@ std::mutex zipMutex; - CaseFile::CaseFile() { isZipOpen = false; caseZipFile = ""; } - void CaseFile::setIsZipOpen(bool isZippOpen) { isZipOpen = isZippOpen; @@ -46,20 +44,19 @@ void CaseFile::renameCaseZipFile(std::string newCaseZipFile) } } - -void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& withinZipPathedFilename, const std::string& fileToAdd) +void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd) { std::lock_guard lock(zipMutex); // for multithreading issue try { - bool doesZipExist = CPLCheckForFile(caseZippFile.c_str(), NULL); + bool doesZipExist = CPLCheckForFile(caseZipFile.c_str(), NULL); if (doesZipExist) { - std::ifstream infile(caseZippFile); + std::ifstream infile(caseZipFile); if (!infile.good()) { - CPLDebug("ZIP", "ZIP file does not exist: %s", caseZippFile.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "ZIP file does not exist: %s", caseZipFile.c_str()); return; } } @@ -67,22 +64,22 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& zipFile zip; if (!doesZipExist) { - zip = cpl_zipOpen(caseZippFile.c_str(), APPEND_STATUS_CREATE); + zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_CREATE); } else { - zip = cpl_zipOpen(caseZippFile.c_str(), APPEND_STATUS_ADDINZIP); + zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_ADDINZIP); } if (zip == NULL) { - CPLDebug("ZIP", "Could not open ZIP: %s", caseZippFile.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "Could not open ZIP: %s", caseZipFile.c_str()); return; } zip_fileinfo zi = {0}; if (cpl_zipOpenNewFileInZip(zip, withinZipPathedFilename.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { - CPLDebug("ZIP", "Could not open new file in ZIP: %s", withinZipPathedFilename.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "Could not open new file in ZIP: %s", withinZipPathedFilename.c_str()); cpl_zipClose(zip, nullptr); return; } @@ -90,7 +87,7 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& VSILFILE *file = VSIFOpenL(fileToAdd.c_str(), "rb"); if (file == nullptr) { - CPLDebug("VSIL", "Could not open file for reading with VSIL: %s", fileToAdd.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "Could not open file for reading with VSIL: %s", fileToAdd.c_str()); cpl_zipCloseFileInZip(zip); cpl_zipClose(zip, nullptr); return; @@ -103,7 +100,7 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& char *data = (char*)CPLMalloc(fileSize); if (data == nullptr) { - CPLDebug("Memory", "Failed to allocate memory for file data."); + CPLError(CE_Failure, CPLE_FileIO, "Failed to allocate memory for file data."); VSIFCloseL(file); cpl_zipCloseFileInZip(zip); cpl_zipClose(zip, nullptr); @@ -112,7 +109,7 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& if (VSIFReadL(data, 1, fileSize, file) != fileSize) { - CPLDebug("FileRead", "Failed to read file contents: %s", withinZipPathedFilename.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents: %s", withinZipPathedFilename.c_str()); CPLFree(data); VSIFCloseL(file); cpl_zipCloseFileInZip(zip); @@ -131,7 +128,7 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& if (cpl_zipClose(zip, nullptr) != ZIP_OK) { - CPLDebug("ZIP", "Error closing ZIP file: %s", caseZippFile.c_str()); + CPLDebug("ZIP", "Error closing ZIP file: %s", caseZipFile.c_str()); } } catch (const std::exception& e) @@ -145,25 +142,7 @@ void CaseFile::addFileToZip(const std::string& caseZippFile, const std::string& } } - -// string splitter, splits an input string into pieces separated by an input delimiter -// used for point initialization in casefile -std::vector CaseFile::split(const std::string &s, const std::string &delimiter) -{ - std::vector tokens; - size_t start = 0; - size_t end = s.find(delimiter); - while (end != std::string::npos) - { - tokens.push_back(s.substr(start, end - start)); - start = end + delimiter.length(); - end = s.find(delimiter, start); - } - tokens.push_back(s.substr(start, end)); - return tokens; -} - -std::string CaseFile::getTime() +std::string CaseFile::getCurrentTime() { auto now = std::chrono::system_clock::now(); std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); @@ -171,15 +150,20 @@ std::string CaseFile::getTime() std::tm* local_tm = std::localtime(&now_time_t); std::ostringstream oss; - oss << std::put_time(local_tm, "%Y-%m-%d %H:%M:%S"); + oss << std::put_time(local_tm, "%Y-%m-%d_%H-%M-%S"); + return oss.str(); } std::string CaseFile::convertDateTimeToStd(const boost::local_time::local_date_time& ninjaTime) { - std::ostringstream ss; - ss.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y%m%d%H%M%S"))); - ss << ninjaTime; - std::string result = ss.str().substr(0, 4) + "-" + ss.str().substr(4, 2) + "-" + ss.str().substr(6, 2) + " " + ss.str().substr(8,2) + ":" + ss.str().substr(10, 2) + ":" + ss.str().substr(12, 2); - return result; + boost::local_time::local_time_facet* facet; + facet = new boost::local_time::local_time_facet(); + facet->format("%Y-%m-%d_%H-%M-%S"); + + std::ostringstream oss; + oss.imbue( std::locale(std::locale::classic(), facet) ); + oss << ninjaTime; + + return oss.str(); } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 2f5d1d25..854ffaa3 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -50,7 +50,6 @@ class CaseFile CaseFile(); - void setIsZipOpen(bool isZippOpen); bool getIsZipOpen(); @@ -58,12 +57,9 @@ class CaseFile std::string getCaseZipFile(); void renameCaseZipFile(std::string newCaseZipFile); + void addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd); - void addFileToZip(const std::string& caseZippFile, const std::string& withinZipPathedFilename, const std::string& fileToAdd); - - - std::vector split(const std::string &s, const std::string &delimiter); - std::string getTime(); + std::string getCurrentTime(); std::string convertDateTimeToStd(const boost::local_time::local_date_time& ninjaTime); }; diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index f3a4e2e9..37bbf8ed 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -518,32 +518,30 @@ int windNinjaCLI(int argc, char* argv[]) std::string inputCfgFile = vm["config_file"].as(); std::string inputCfgFilename = CPLGetFilename( inputCfgFile.c_str() ); - casefile.addFileToZip(zipFile, inputCfgFilename, inputCfgFile); + casefile.addFileToZip(inputCfgFilename, inputCfgFile); std::string demFile = vm["elevation_file"].as(); std::string demFilename = CPLGetFilename( demFile.c_str() ); - casefile.addFileToZip(zipFile, demFilename, demFile); - casefile.addFileToZip(zipFile, mainCaseCfgFilename, mainCaseCfgFile); + casefile.addFileToZip(demFilename, demFile); + casefile.addFileToZip(mainCaseCfgFilename, mainCaseCfgFile); VSIUnlink( mainCaseCfgFile.c_str() ); if (vm.count("forecast_filename")) { std::string weatherFile = vm["forecast_filename"].as(); std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); - casefile.addFileToZip(zipFile, weatherZipPathFile, weatherFile); + casefile.addFileToZip(weatherZipPathFile, weatherFile); } if (vm.count("wx_station_filename")) { std::string pointFile = vm["wx_station_filename"].as(); - std::vector tokens = casefile.split(pointFile, "/"); std::string pointFilename = CPLGetFilename( pointFile.c_str() ); - if (tokens.size() >= 2) { - std::string secondToLastToken = tokens[tokens.size()-2]; - if (secondToLastToken.find("WXSTATIONS-") != std::string::npos) { - pointFilename = secondToLastToken + "/" + tokens[tokens.size() - 1]; - } + std::string pointPath = CPLGetPath( pointFile.c_str() ); + if (pointPath.find("WXSTATIONS-") != std::string::npos) + { + pointFilename = CPLFormFilename(CPLGetFilename(pointPath.c_str()), pointFilename.c_str(), ""); } std::string pointZipPathFile = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); - casefile.addFileToZip(zipFile, pointZipPathFile, pointFile); + casefile.addFileToZip(pointZipPathFile, pointFile); } } diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index e1f64bb7..450cdee6 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2833,18 +2833,16 @@ void ninja::writeOutputFiles() std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) { - std::string getlocaltime = casefile->getTime(); - timestr = getlocaltime; + timestr = casefile->getCurrentTime(); } else { timestr = casefile->convertDateTimeToStd(input.ninjaTime); } - std::string zipFile = casefile->getCaseZipFile(); std::string volVtkZipPathFile = CPLFormFilename(timestr.c_str(), volVtkFilename.c_str(), ""); - casefile->addFileToZip(zipFile, volVtkZipPathFile, input.volVTKFile); + casefile->addFileToZip(volVtkZipPathFile, input.volVTKFile); std::string volVtkSurfZipPathFile = CPLFormFilename(timestr.c_str(), volVtkSurfFilename.c_str(), ""); - casefile->addFileToZip(zipFile, volVtkSurfZipPathFile, volVtkSurfFile); + casefile->addFileToZip(volVtkSurfZipPathFile, volVtkSurfFile); } if( input.volVTKOutFlag == false ) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 9978bdc3..bfa3b858 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -2712,18 +2712,16 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) { - std::string getlocaltime = casefile->getTime(); - timestr = getlocaltime; + timestr = casefile->getCurrentTime(); } else { timestr = casefile->convertDateTimeToStd(input.ninjaTime); } - std::string zipFile = casefile->getCaseZipFile(); std::string massMeshVtkZipPathFile = CPLFormFilename(timestr.c_str(), massMeshVtkFilename.c_str(), ""); - casefile->addFileToZip(zipFile, massMeshVtkZipPathFile, massMeshVtkFile); + casefile->addFileToZip(massMeshVtkZipPathFile, massMeshVtkFile); std::string massMeshVtkSurfZipPathFile = CPLFormFilename(timestr.c_str(), massMeshVtkSurfFilename.c_str(), ""); - casefile->addFileToZip(zipFile, massMeshVtkSurfZipPathFile, massMeshVtkSurfFile); + casefile->addFileToZip(massMeshVtkSurfZipPathFile, massMeshVtkSurfFile); } if( writeMassMeshVtk == false ) From 00da1e4a918867919c1ffaee1feedefcd04a0125 Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 31 Mar 2025 20:16:16 -0600 Subject: [PATCH 26/35] changes required to compile the casefile-updated branch on windows. For issue #7 while it compiled, and ran in what ways it could, all the cpl_zip() type commands had to be commented out, so it isn\'t doing any zipping stuff anymore. The error is stuff like, "unresolved external symbol to cpl_zipOpen". So it seems like a change that needs to be made to CMakeLists.txt to include zlib. I see zlib inside the included GIS_INTERNALS, but it doesn\'t seem to be getting grabbed correctly. I tried building zlib from scratch, GIS_INTERNALS is using zlib 1.2.3 but I could only get ahold of the current zlib which was version 1.3.1. I\'m not sure if the problem was this zlib version difference, or if something else was missing, maybe some edits to how gdal is included to point to zlib or another path to something more specific in zlib, but including zlib this way didn\'t seem to fix the problem. Note that in casefile, the include is "#include "cpl_minizip_zip.h"", so maybe it\'s some other slightly missed include I think most of the other changes are good, except that the static_casts to get std::to_string(intVal) need to be checked, on both Ubuntu and Windows, to make sure that they don't mess up the printed values by adding decimals and stuff. Not sure what to do about "#include ", it wasn't Windows compatible. Seemed like it wasn\'t outputting the intermediate log files, might be a good thing, might not, need to check and make sure that the failing of the zip file to open is properly being handled in the later intermediate file outputs. --- src/gui/mainWindow.cpp | 53 ++++++++++++++++++++++------------- src/gui/pointInput.cpp | 4 ++- src/ninja/Elevation.cpp | 2 +- src/ninja/casefile.cpp | 62 +++++++++++++++++++++-------------------- src/ninja/casefile.h | 2 +- src/ninja/cli.cpp | 11 ++++---- src/ninja/windninja.h | 5 ++++ 7 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index c8b0a173..df6b3be0 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1831,7 +1831,7 @@ int mainWindow::solve() } if (writeCF && customMesh) { - mainCaseCfgFILE << "--mesh_resolution " << std::to_string(meshRes) << "\n"; + mainCaseCfgFILE << "--mesh_resolution " << std::to_string(static_cast(meshRes)) << "\n"; } #ifdef NINJAFOAM @@ -1926,7 +1926,7 @@ int mainWindow::solve() //input wind height double inHeight = tree->wind->metaWind->inputHeightDoubleSpinBox->value(); if (writeCF) { - mainCaseCfgFILE << "--input_wind_height " << std::to_string(inHeight) << "\n"; + mainCaseCfgFILE << "--input_wind_height " << std::to_string(static_cast(inHeight)) << "\n"; } lengthUnits::eLengthUnits inHeightUnits; if(tree->wind->metaWind->feetRadioButton->isChecked()) @@ -2005,7 +2005,7 @@ int mainWindow::solve() //output height double outHeight = tree->output->outputHeight->outputHeightDoubleSpinBox->value(); if (writeCF) { - mainCaseCfgFILE << "--output_wind_height " << std::to_string(outHeight) << "\n"; + mainCaseCfgFILE << "--output_wind_height " << std::to_string(static_cast(outHeight)) << "\n"; } lengthUnits::eLengthUnits outHeightUnits; if(tree->output->outputHeight->feetRadioButton->isChecked()) @@ -2054,7 +2054,7 @@ int mainWindow::solve() if (writeCF) { //if (clip > 0) //{ - mainCaseCfgFILE << "--output_buffer_clipping " << std::to_string(clip) << "\n"; + mainCaseCfgFILE << "--output_buffer_clipping " << std::to_string(static_cast(clip)) << "\n"; //} } @@ -2073,7 +2073,7 @@ int mainWindow::solve() { mainCaseCfgFILE << "--write_wx_model_goog_output true\n"; } - mainCaseCfgFILE << "--goog_out_resolution " << std::to_string(googleRes) << "\n"; + mainCaseCfgFILE << "--goog_out_resolution " << std::to_string(static_cast(googleRes)) << "\n"; } } double vectorWidth = tree->google->vectorWidthDoubleSpinBox->value(); @@ -2193,7 +2193,7 @@ int mainWindow::solve() { mainCaseCfgFILE << "--write_wx_model_ascii_output true\n"; } - mainCaseCfgFILE << "--ascii_out_resolution " << std::to_string(fbRes) << "\n"; + mainCaseCfgFILE << "--ascii_out_resolution " << std::to_string(static_cast(fbRes)) << "\n"; } } lengthUnits::eLengthUnits fbUnits; @@ -2255,7 +2255,7 @@ int mainWindow::solve() { mainCaseCfgFILE << "--write_wx_model_shapefile_output true\n"; } - mainCaseCfgFILE << "--shape_out_resolution " << std::to_string(shapeRes) << "\n"; + mainCaseCfgFILE << "--shape_out_resolution " << std::to_string(static_cast(shapeRes)) << "\n"; } } lengthUnits::eLengthUnits shapeUnits; @@ -2281,8 +2281,8 @@ int mainWindow::solve() if (writePdf) { mainCaseCfgFILE << "--write_pdf_output true\n"; - mainCaseCfgFILE << "--pdf_out_resolution "<< std::to_string(pdfRes) << "\n"; - mainCaseCfgFILE << "--pdf_linewidth "<< std::to_string(pdfLineWidth) << "\n"; + mainCaseCfgFILE << "--pdf_out_resolution "<< std::to_string(static_cast(pdfRes)) << "\n"; + mainCaseCfgFILE << "--pdf_linewidth "<< std::to_string(static_cast(pdfLineWidth)) << "\n"; } } lengthUnits::eLengthUnits pdfUnits; @@ -2357,7 +2357,7 @@ int mainWindow::solve() //number of processors int nThreads = tree->solve->numProcSpinBox->value(); if (writeCF) { - mainCaseCfgFILE << "--num_threads " << std::to_string(nThreads) << "\n"; + mainCaseCfgFILE << "--num_threads " << std::to_string(static_cast(nThreads)) << "\n"; } army = new ninjaArmy(); @@ -2396,7 +2396,7 @@ int mainWindow::solve() } else { mainCaseCfgFILE << "--fetch_current_station_data false\n"; - mainCaseCfgFILE << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + mainCaseCfgFILE << "--number_time_steps " << std::to_string(static_cast(numTimeSteps)) << "\n"; } } else // if (tree->point->xWidget != NULL && tree->point->xWidget->get_wasStationFetched() == true) { @@ -2414,7 +2414,7 @@ int mainWindow::solve() mainCaseCfgFILE << "--stop_day " << xEndTime[2] << "\n"; mainCaseCfgFILE << "--stop_hour " << xEndTime[3] << "\n"; mainCaseCfgFILE << "--stop_minute " << xEndTime[4] << "\n"; - mainCaseCfgFILE << "--number_time_steps " << std::to_string(numTimeSteps) << "\n"; + mainCaseCfgFILE << "--number_time_steps " << std::to_string(static_cast(numTimeSteps)) << "\n"; } else { mainCaseCfgFILE << "--fetch_current_station_data true\n"; @@ -2439,8 +2439,9 @@ int mainWindow::solve() // for each file append it to csv // if any point file is under a wx station folder just copy the entire folder over - otherwise no std::vector fullFileListPoint = tree->point->fullFileList; - for (std::string & pointFile : fullFileListPoint) + for( size_t pIdx = 0; pIdx < fullFileListPoint.size(); pIdx++ ) { + std::string pointFile = fullFileListPoint[pIdx]; std::string pointFilename = CPLGetFilename( pointFile.c_str() ); std::string pointPath = CPLGetPath( pointFile.c_str() ); if (pointPath.find("WXSTATIONS-") != std::string::npos) @@ -2468,8 +2469,9 @@ int mainWindow::solve() delete army; return false; } - for (std::string & pointFile : pointFileList) + for( size_t pIdx = 0; pIdx < pointFileList.size(); pIdx++ ) { + std::string pointFile = pointFileList[pIdx]; std::string pointFilename = CPLGetFilename( pointFile.c_str() ); std::string pointPath = CPLGetPath( pointFile.c_str() ); if (pointPath.find("WXSTATIONS-") != std::string::npos) @@ -2789,11 +2791,17 @@ int mainWindow::solve() std::vector stringTimes; blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - for (const auto& time : times) + for( size_t tIdx = 0; tIdx < times.size(); tIdx++ ) { + blt::local_date_time time = times[tIdx]; + // Convert local_date_time to ptime using the UTC time zone // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); + //bpt::ptime pt = bpt::from_iso_string(time); + //blt::local_date_time ldt = blt::local_date_time(pt, utc); + //ldt = ldt.local_time_in(zone); + //pt = bpt::from_iso_string(time); // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); @@ -2861,13 +2869,20 @@ int mainWindow::solve() std::vector fullTimesList = tree->weather->getFullTimeList(); std::vector stringTimes; + //blt::time_zone_ptr zone = globalTimeZoneDB.time_zone_from_region(timeZone.c_str()); blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); - for (const auto& time : fullTimesList) + for( size_t tIdx = 0; tIdx < fullTimesList.size(); tIdx++ ) { + blt::local_date_time time = times[tIdx]; + // Convert local_date_time to ptime using the UTC time zone // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); + //bpt::ptime pt = bpt::from_iso_string(time); + //blt::local_date_time ldt = blt::local_date_time(pt, utc); + //ldt = ldt.local_time_in(zone); + //pt = bpt::from_iso_string(time); // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); @@ -2906,7 +2921,7 @@ int mainWindow::solve() army->setCaseFilePtr( i, casefile ); // add runs to files - std::string domainRunCfgFilename = "run" + std::to_string(i) + "-DomainAverage.cfg"; + std::string domainRunCfgFilename = "run" + std::to_string(static_cast(i)) + "-DomainAverage.cfg"; std::string domainRunCfgFile = CPLFormFilename(outputDir.c_str(), domainRunCfgFilename.c_str(), ""); std::ofstream domainRunFILE; if (writeCF) @@ -2956,14 +2971,14 @@ int mainWindow::solve() { //get speed if (writeCF) { - mainCaseCfgFILE << "--input_speed " << std::to_string(tree->wind->windTable->speed[i]->value()) << "\n"; + mainCaseCfgFILE << "--input_speed " << std::to_string(static_cast(tree->wind->windTable->speed[i]->value())) << "\n"; } army->setInputSpeed( i, tree->wind->windTable->speed[i]->value(), inputSpeedUnits); //get direction if (writeCF) { - mainCaseCfgFILE << "--input_direction " << std::to_string(tree->wind->windTable->dir[i]->value()) << "\n"; + mainCaseCfgFILE << "--input_direction " << std::to_string(static_cast(tree->wind->windTable->dir[i]->value())) << "\n"; } army->setInputDirection( i, tree->wind->windTable->dir[i]->value() ); diff --git a/src/gui/pointInput.cpp b/src/gui/pointInput.cpp index 2938a7e3..f88ce97e 100644 --- a/src/gui/pointInput.cpp +++ b/src/gui/pointInput.cpp @@ -295,8 +295,10 @@ void pointInput::generateFullFileList() collectAllIndexes(rootIndex, allIndexes); - for (const QModelIndex &index : allIndexes) + for( size_t qIdx = 0; qIdx < allIndexes.size(); qIdx++ ) { + const QModelIndex &index = allIndexes[qIdx]; + // Check if it is a file if (!sfModel->isDir(index)) { diff --git a/src/ninja/Elevation.cpp b/src/ninja/Elevation.cpp index dcb98713..cbac4458 100644 --- a/src/ninja/Elevation.cpp +++ b/src/ninja/Elevation.cpp @@ -166,7 +166,7 @@ void Elevation::smooth_elevation(const int smoothDist) { if( smoothDist < 1 ) { - throw std::runtime_error("input smoothDist "+std::to_string(smoothDist)+" for Elevation::smooth_elevation() is not 1 or greater!"); + throw std::runtime_error("input smoothDist "+std::to_string(static_cast(smoothDist))+" for Elevation::smooth_elevation() is not 1 or greater!"); } Elevation dem; // make a temporary copy to keep the calculation values the same diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index d3e39dcc..edbabe7b 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -1,6 +1,6 @@ #include "casefile.h" -std::mutex zipMutex; +//std::mutex zipMutex; CaseFile::CaseFile() { @@ -46,10 +46,10 @@ void CaseFile::renameCaseZipFile(std::string newCaseZipFile) void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd) { - std::lock_guard lock(zipMutex); // for multithreading issue + //std::lock_guard lock(zipMutex); // for multithreading issue try { - bool doesZipExist = CPLCheckForFile(caseZipFile.c_str(), NULL); + bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); if (doesZipExist) { @@ -64,10 +64,10 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st zipFile zip; if (!doesZipExist) { - zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_CREATE); + //zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_CREATE); } else { - zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_ADDINZIP); + //zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_ADDINZIP); } if (zip == NULL) @@ -77,19 +77,19 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st } zip_fileinfo zi = {0}; - if (cpl_zipOpenNewFileInZip(zip, withinZipPathedFilename.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) - { - CPLError(CE_Failure, CPLE_FileIO, "Could not open new file in ZIP: %s", withinZipPathedFilename.c_str()); - cpl_zipClose(zip, nullptr); - return; - } + //if (cpl_zipOpenNewFileInZip(zip, withinZipPathedFilename.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) + //{ + // CPLError(CE_Failure, CPLE_FileIO, "Could not open new file in ZIP: %s", withinZipPathedFilename.c_str()); + // cpl_zipClose(zip, nullptr); + // return; + //} VSILFILE *file = VSIFOpenL(fileToAdd.c_str(), "rb"); if (file == nullptr) { CPLError(CE_Failure, CPLE_FileIO, "Could not open file for reading with VSIL: %s", fileToAdd.c_str()); - cpl_zipCloseFileInZip(zip); - cpl_zipClose(zip, nullptr); + //cpl_zipCloseFileInZip(zip); + //cpl_zipClose(zip, nullptr); return; } @@ -102,8 +102,8 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st { CPLError(CE_Failure, CPLE_FileIO, "Failed to allocate memory for file data."); VSIFCloseL(file); - cpl_zipCloseFileInZip(zip); - cpl_zipClose(zip, nullptr); + //cpl_zipCloseFileInZip(zip); + //cpl_zipClose(zip, nullptr); return; } @@ -112,24 +112,24 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents: %s", withinZipPathedFilename.c_str()); CPLFree(data); VSIFCloseL(file); - cpl_zipCloseFileInZip(zip); - cpl_zipClose(zip, nullptr); + //cpl_zipCloseFileInZip(zip); + //cpl_zipClose(zip, nullptr); return; } - if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) - { - CPLDebug("ZIP", "Error writing data to ZIP file: %s", withinZipPathedFilename.c_str()); - } + //if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) + //{ + // CPLDebug("ZIP", "Error writing data to ZIP file: %s", withinZipPathedFilename.c_str()); + //} CPLFree(data); VSIFCloseL(file); - cpl_zipCloseFileInZip(zip); + //cpl_zipCloseFileInZip(zip); - if (cpl_zipClose(zip, nullptr) != ZIP_OK) - { - CPLDebug("ZIP", "Error closing ZIP file: %s", caseZipFile.c_str()); - } + //if (cpl_zipClose(zip, nullptr) != ZIP_OK) + //{ + // CPLDebug("ZIP", "Error closing ZIP file: %s", caseZipFile.c_str()); + //} } catch (const std::exception& e) { @@ -144,13 +144,15 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st std::string CaseFile::getCurrentTime() { - auto now = std::chrono::system_clock::now(); - std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + const boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - std::tm* local_tm = std::localtime(&now_time_t); + boost::local_time::local_time_facet* facet; + facet = new boost::local_time::local_time_facet(); + facet->format("%Y-%m-%d_%H-%M-%S"); std::ostringstream oss; - oss << std::put_time(local_tm, "%Y-%m-%d_%H-%M-%S"); + oss.imbue( std::locale(std::locale::classic(), facet) ); + oss << now; return oss.str(); } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 854ffaa3..039f5cef 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -34,7 +34,7 @@ #include #include #include "cpl_minizip_zip.h" -#include +//#include #include #include diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 56122169..66913281 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -475,10 +475,10 @@ int windNinjaCLI(int argc, char* argv[]) return 1; } - for (const auto& pair : vm) + for( po::variables_map::iterator pair = vm.begin(); pair != vm.end(); pair++ ) { - const std::string& option_name = pair.first; - const po::variable_value& option_value = pair.second; + const std::string& option_name = pair->first; + const po::variable_value& option_value = pair->second; mainCaseCfgFILE << "--" << option_name << " "; @@ -497,9 +497,10 @@ int windNinjaCLI(int argc, char* argv[]) mainCaseCfgFILE << option_value.as() << std::endl; } else if (option_value.value().type() == typeid(std::vector)) { - const auto& vec = option_value.as>(); - for (const auto& str : vec) + std::vector vec = option_value.as>(); + for( size_t vIdx = 0; vIdx < vec.size(); vIdx++ ) { + std::string str = vec[vIdx]; mainCaseCfgFILE << str << " "; } mainCaseCfgFILE << std::endl; diff --git a/src/ninja/windninja.h b/src/ninja/windninja.h index 7b84b5fa..299585a5 100644 --- a/src/ninja/windninja.h +++ b/src/ninja/windninja.h @@ -63,7 +63,12 @@ WN_C_START #include //#include +#ifdef WIN32 +#define false 0 +#define true 1 +#else #include +#endif //Use structs instead of void * for type checking by C compilier struct NinjaArmyH; From a1874cf34369e062c1cfdbd8d7f3d2b14232233f Mon Sep 17 00:00:00 2001 From: latwood Date: Tue, 1 Apr 2025 17:37:21 -0600 Subject: [PATCH 27/35] fixes to the last casefile commit, my changes for building on windows broke a few of the time methods, plus a little bit of cleanup to the changes for building on windows commit. Tested and seems the static_cast(intVal) didn't seem to hurt stuff as much as I thought it would. For issue #7 --- src/gui/mainWindow.cpp | 17 ++++++----------- src/ninja/Elevation.cpp | 2 +- src/ninja/casefile.cpp | 4 ++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index df6b3be0..c25aabeb 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -2789,6 +2789,7 @@ int mainWindow::solve() if (writeCF && times.size() > 0) { std::vector stringTimes; + //blt::time_zone_ptr zone = globalTimeZoneDB.time_zone_from_region(timeZone.c_str()); blt::time_zone_ptr utc = globalTimeZoneDB.time_zone_from_region("UTC"); for( size_t tIdx = 0; tIdx < times.size(); tIdx++ ) @@ -2796,12 +2797,9 @@ int mainWindow::solve() blt::local_date_time time = times[tIdx]; // Convert local_date_time to ptime using the UTC time zone - // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); - //bpt::ptime pt = bpt::from_iso_string(time); - //blt::local_date_time ldt = blt::local_date_time(pt, utc); - //ldt = ldt.local_time_in(zone); - //pt = bpt::from_iso_string(time); + // Convert local_date_time to ptime using the data time zone + //bpt::ptime pt = time.local_time_in(zone).local_time(); // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); @@ -2874,15 +2872,12 @@ int mainWindow::solve() for( size_t tIdx = 0; tIdx < fullTimesList.size(); tIdx++ ) { - blt::local_date_time time = times[tIdx]; + blt::local_date_time time = fullTimesList[tIdx]; // Convert local_date_time to ptime using the UTC time zone - // Get the local time in the UTC time zone bpt::ptime pt = time.local_time_in(utc).local_time(); - //bpt::ptime pt = bpt::from_iso_string(time); - //blt::local_date_time ldt = blt::local_date_time(pt, utc); - //ldt = ldt.local_time_in(zone); - //pt = bpt::from_iso_string(time); + // Convert local_date_time to ptime using the data time zone + //bpt::ptime pt = time.local_time_in(zone).local_time(); // Convert ptime to ISO 8601 string std::string isoString = bpt::to_iso_string(pt); diff --git a/src/ninja/Elevation.cpp b/src/ninja/Elevation.cpp index cbac4458..97b4a3db 100644 --- a/src/ninja/Elevation.cpp +++ b/src/ninja/Elevation.cpp @@ -166,7 +166,7 @@ void Elevation::smooth_elevation(const int smoothDist) { if( smoothDist < 1 ) { - throw std::runtime_error("input smoothDist "+std::to_string(static_cast(smoothDist))+" for Elevation::smooth_elevation() is not 1 or greater!"); + throw std::runtime_error("input smoothDist "+std::to_string(static_cast(smoothDist))+" for Elevation::smooth_elevation() is not 1 or greater!"); } Elevation dem; // make a temporary copy to keep the calculation values the same diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index edbabe7b..8b53755b 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -146,8 +146,8 @@ std::string CaseFile::getCurrentTime() { const boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - boost::local_time::local_time_facet* facet; - facet = new boost::local_time::local_time_facet(); + boost::posix_time::time_facet* facet; + facet = new boost::posix_time::time_facet(); facet->format("%Y-%m-%d_%H-%M-%S"); std::ostringstream oss; From f054fa7dc8c39545de897def14de82caa5254999 Mon Sep 17 00:00:00 2001 From: latwood Date: Tue, 1 Apr 2025 18:00:37 -0600 Subject: [PATCH 28/35] attempted to fix the minizip "unresolved external symbol to cpl_zipOpen" type problems for windows builds of the casefile. For issue #7 I was not successful at getting minizip to work on windows, the following changes didn't hurt Ubuntu builds they just showed more specifically the libs found behind the scenes for minizip, but it was required to even attempt to get minizip through zlib to work on windows. I specified the libraries to the GIS_INTERNALS locations, then later to a hand built older minizip (https://www.winimage.com/zLibDll/minizip.html to find https://github.com/zlib-ng/minizip-ng/tree/1.2) and a handbuilt zlib of version 1.2.8, neither method fixed the problem. Seems to imply that the issue isn't minizip in zlib by itself, but that minizip in zlib has to be built correctly into gdal itself, which doesn't seem to be done for our GIS_INTERNALS windows build. Using "dumpbin" on the ".lib" files in GIS_INTERNALS, I was able to find that there are minizip bindings somewhere in there, but apparently GDAL somehow isn't built with them, the linking is somehow broken. Because of this, I think that we are going to need to try some other zip method that is more compatible with our windows builds. --- CMakeLists.txt | 6 ++++++ src/ninja/CMakeLists.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 564b5814..c5b9e651 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,13 +117,19 @@ ELSE(USE_VCPKG) if(NOT GIS_INTERNALS_HOME) find_package(NetCDF REQUIRED) find_package(GDAL REQUIRED) + find_package(ZLIB REQUIRED) + find_library(MINIZIP_LIBRARY NAMES minizip) else(NOT GIS_INTERNALS_HOME) find_package(NetCDF) find_package(GDAL) + find_package(ZLIB REQUIRED) + find_library(MINIZIP_LIBRARY NAMES minizip) endif(NOT GIS_INTERNALS_HOME) else(WIN32) find_package(NetCDF REQUIRED) find_package(GDAL REQUIRED) + find_package(ZLIB REQUIRED) + find_library(MINIZIP_LIBRARY NAMES minizip) endif(WIN32) endif(USE_VCPKG) option(NINJA_QT5GUI "build Qt5 experimental GUI" OFF) diff --git a/src/ninja/CMakeLists.txt b/src/ninja/CMakeLists.txt index cd381a3f..c611a8d4 100644 --- a/src/ninja/CMakeLists.txt +++ b/src/ninja/CMakeLists.txt @@ -127,6 +127,8 @@ endif(WITH_NOMADS_SUPPORT) set(LINK_LIBS ${NETCDF_LIBRARIES_C} ${GDAL_LIBRARY} + ${ZLIB_LIBRARY} + ${MINIZIP_LIBRARY} ${CURL_LIBRARIES} ${Boost_LIBRARIES}) From 2831fe838b4a6183c025c593d51b715eb6126457 Mon Sep 17 00:00:00 2001 From: latwood Date: Wed, 2 Apr 2025 17:55:21 -0600 Subject: [PATCH 29/35] reverted casefile minizip back to standard GDAL VSI style zipping methods, first pass with GDAL zipping methods. for issue #7 still had to keep #include , windows issue causing lib, to get this style of zipping to work without seg faulting for the 5 wxModel data times, none selected, case on Ubuntu. Still haven't found a workaround for with the Windows build the windows build is now compiling with zipping, but VSIRename\(\) is causing problems with the current setup. In particular, it doesn't seem to matter how the file paths are fed into VSIRename\(\), VSIRename\(\) will rename the zip file regardless of whether it has uniform or a mix of "/" or "\" style chars. But while VSIRename\(\) works on an open zip file on Ubuntu, VSIRename\(\) will fail on Windows unless the zip file is closed and reopened during the renaming process. Worse, while all the folders and files are added to the zip properly when VSIRename\(\) fails to rename the zip, when VSIRename\(\) succeeds in renaming the zip it somehow drops most of the files from within the zip. there are pathing problems that need to be addressed for the windows build, apparently the gui grabs the dem file with "C:/Location" "/" style chars, but CPLFormFilename\(\) puts the remaining parts of the path together with "\" style chars, mixing the path char type. In addition, the paths seen in the various files within the zip get to be "\" in style, need to make sure that style makes sense. My current method attempted to avoid reopening and reclosing the zip over and over at each addFileToZip\(\) instance, by just opening the zip once at the beginning, and closing the zip once at the end. It seemed to work, at least till I hit the windows issues, but I'm not sure whether it is wise to leave the zip file hanging open like that the whole time. It does look like the method will work though, once we get the zip file renaming and the syncing type issues figured out. Will probably need to watch out for properly closing the zip for each instance of the program quitting early though. --- CMakeLists.txt | 6 --- src/gui/mainWindow.cpp | 3 ++ src/ninja/CMakeLists.txt | 2 - src/ninja/casefile.cpp | 97 ++++++++++++++++++++++++---------------- src/ninja/casefile.h | 7 ++- src/ninja/cli.cpp | 2 + 6 files changed, 68 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5b9e651..564b5814 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,19 +117,13 @@ ELSE(USE_VCPKG) if(NOT GIS_INTERNALS_HOME) find_package(NetCDF REQUIRED) find_package(GDAL REQUIRED) - find_package(ZLIB REQUIRED) - find_library(MINIZIP_LIBRARY NAMES minizip) else(NOT GIS_INTERNALS_HOME) find_package(NetCDF) find_package(GDAL) - find_package(ZLIB REQUIRED) - find_library(MINIZIP_LIBRARY NAMES minizip) endif(NOT GIS_INTERNALS_HOME) else(WIN32) find_package(NetCDF REQUIRED) find_package(GDAL REQUIRED) - find_package(ZLIB REQUIRED) - find_library(MINIZIP_LIBRARY NAMES minizip) endif(WIN32) endif(USE_VCPKG) option(NINJA_QT5GUI "build Qt5 experimental GUI" OFF) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index c25aabeb..f8506530 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1686,6 +1686,7 @@ int mainWindow::solve() setCursor(Qt::ArrowCursor); //Restart everything return false; } + //std::replace(outputDir.begin(),outputDir.end(), '/', '\\'); bool writeCF = tree->solve->CaseFileBox->isChecked(); @@ -1702,6 +1703,7 @@ int mainWindow::solve() if (writeCF) { casefile.setIsZipOpen(true); casefile.setCaseZipFile(zipFile); + casefile.openCaseZipFile(); mainCaseCfgFILE.open(mainCaseCfgFile); //if (!mainCaseCfgFILE.is_open()) // useful for debugging if (!mainCaseCfgFILE) @@ -3201,6 +3203,7 @@ int mainWindow::solve() //start the army try { ninjaSuccess = army->startRuns( nThreads ); + casefile.closeCaseZipFile(); } catch (bad_alloc& e) { diff --git a/src/ninja/CMakeLists.txt b/src/ninja/CMakeLists.txt index c611a8d4..cd381a3f 100644 --- a/src/ninja/CMakeLists.txt +++ b/src/ninja/CMakeLists.txt @@ -127,8 +127,6 @@ endif(WITH_NOMADS_SUPPORT) set(LINK_LIBS ${NETCDF_LIBRARIES_C} ${GDAL_LIBRARY} - ${ZLIB_LIBRARY} - ${MINIZIP_LIBRARY} ${CURL_LIBRARIES} ${Boost_LIBRARIES}) diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 8b53755b..4df231ea 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -1,11 +1,12 @@ #include "casefile.h" -//std::mutex zipMutex; +std::mutex zipMutex; CaseFile::CaseFile() { isZipOpen = false; caseZipFile = ""; + zipHandle = NULL; } void CaseFile::setIsZipOpen(bool isZippOpen) @@ -33,20 +34,43 @@ void CaseFile::renameCaseZipFile(std::string newCaseZipFile) { if (strcmp( CPLGetFilename( caseZipFile.c_str() ), "tmp.ninja" ) == 0) { + //closeCaseZipFile(); + //std::replace(caseZipFile.begin(),caseZipFile.end(), '\\', '/'); + //std::replace(newCaseZipFile.begin(),newCaseZipFile.end(), '\\', '/'); if (VSIRename(caseZipFile.c_str(), newCaseZipFile.c_str()) == 0) { CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", caseZipFile.c_str(), newCaseZipFile.c_str()); + //printf("ZIP_RENAME: Successfully renamed %s to %s\n", caseZipFile.c_str(), newCaseZipFile.c_str()); caseZipFile = newCaseZipFile; } else { CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", caseZipFile.c_str(), newCaseZipFile.c_str()); } + //openCaseZipFile(); } } +void CaseFile::openCaseZipFile() +{ + //bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); +std::cout << "openingCaseZipFile" << std::endl; + zipHandle = CPLCreateZip(caseZipFile.c_str(), NULL); + if (zipHandle == NULL) + { + CPLError(CE_Failure, CPLE_FileIO, "Failed to create or open zip file: %s", caseZipFile.c_str()); + } +} + +void CaseFile::closeCaseZipFile() +{ +std::cout << "closingCaseZipFile" << std::endl; + CPLCloseZip(zipHandle); + zipHandle = NULL; +} + void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd) { - //std::lock_guard lock(zipMutex); // for multithreading issue + std::lock_guard lock(zipMutex); // for multithreading issue try { bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); @@ -56,80 +80,75 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st std::ifstream infile(caseZipFile); if (!infile.good()) { - CPLError(CE_Failure, CPLE_FileIO, "ZIP file does not exist: %s", caseZipFile.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "ZIP file REALLY does not exist: %s", caseZipFile.c_str()); return; } - } - - zipFile zip; - if (!doesZipExist) - { - //zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_CREATE); } else { - //zip = cpl_zipOpen(caseZipFile.c_str(), APPEND_STATUS_ADDINZIP); + CPLError(CE_Failure, CPLE_FileIO, "ZIP file does not exist: %s", caseZipFile.c_str()); + return; } - if (zip == NULL) + if (zipHandle == NULL) { - CPLError(CE_Failure, CPLE_FileIO, "Could not open ZIP: %s", caseZipFile.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "tried to add file to unopened ZIP: %s", caseZipFile.c_str()); return; } - zip_fileinfo zi = {0}; - //if (cpl_zipOpenNewFileInZip(zip, withinZipPathedFilename.c_str(), &zi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) - //{ - // CPLError(CE_Failure, CPLE_FileIO, "Could not open new file in ZIP: %s", withinZipPathedFilename.c_str()); - // cpl_zipClose(zip, nullptr); - // return; - //} - + // read in the file data to be copied to the zip VSILFILE *file = VSIFOpenL(fileToAdd.c_str(), "rb"); if (file == nullptr) { CPLError(CE_Failure, CPLE_FileIO, "Could not open file for reading with VSIL: %s", fileToAdd.c_str()); - //cpl_zipCloseFileInZip(zip); - //cpl_zipClose(zip, nullptr); + closeCaseZipFile(); return; } VSIFSeekL(file, 0, SEEK_END); vsi_l_offset fileSize = VSIFTellL(file); - VSIFSeekL(file, 0, SEEK_SET); + VSIFSeekL(file, 0, SEEK_SET); // rather than VSIRewindL(file);? char *data = (char*)CPLMalloc(fileSize); if (data == nullptr) { CPLError(CE_Failure, CPLE_FileIO, "Failed to allocate memory for file data."); VSIFCloseL(file); - //cpl_zipCloseFileInZip(zip); - //cpl_zipClose(zip, nullptr); + closeCaseZipFile(); return; } if (VSIFReadL(data, 1, fileSize, file) != fileSize) { - CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents: %s", withinZipPathedFilename.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents: %s", fileToAdd.c_str()); CPLFree(data); VSIFCloseL(file); - //cpl_zipCloseFileInZip(zip); - //cpl_zipClose(zip, nullptr); + closeCaseZipFile(); return; } - //if (cpl_zipWriteInFileInZip(zip, data, static_cast(fileSize)) != ZIP_OK) - //{ - // CPLDebug("ZIP", "Error writing data to ZIP file: %s", withinZipPathedFilename.c_str()); - //} - - CPLFree(data); VSIFCloseL(file); - //cpl_zipCloseFileInZip(zip); - //if (cpl_zipClose(zip, nullptr) != ZIP_OK) - //{ - // CPLDebug("ZIP", "Error closing ZIP file: %s", caseZipFile.c_str()); - //} + // add the file data to the zip + if (CPLCreateFileInZip(zipHandle, withinZipPathedFilename.c_str(), NULL) != CE_None) { + CPLError(CE_Failure, CPLE_FileIO, "Failed to create file in zip: %s", withinZipPathedFilename.c_str()); + CPLFree(data); + CPLCloseZip(zipHandle); + return; + } + + if (CPLWriteFileInZip(zipHandle, data, static_cast(fileSize)) != CE_None) { + CPLError(CE_Failure, CPLE_FileIO, "Failed to write data to file in zip: %s", withinZipPathedFilename.c_str()); + CPLFree(data); + CPLCloseZip(zipHandle); + } + + if (CPLCloseFileInZip(zipHandle) != CE_None) { + CPLError(CE_Failure, CPLE_FileIO, "Failed to close file in zip: %s", withinZipPathedFilename.c_str()); + CPLFree(data); + CPLCloseZip(zipHandle); + } + + CPLFree(data); } catch (const std::exception& e) { diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 039f5cef..723d2932 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -33,8 +33,7 @@ #include #include #include -#include "cpl_minizip_zip.h" -//#include +#include #include #include @@ -45,6 +44,7 @@ class CaseFile bool isZipOpen; std::string caseZipFile; + void* zipHandle; public: @@ -57,6 +57,9 @@ class CaseFile std::string getCaseZipFile(); void renameCaseZipFile(std::string newCaseZipFile); + void openCaseZipFile(); + void closeCaseZipFile(); + void addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd); std::string getCurrentTime(); diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 66913281..fbec1a06 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -467,6 +467,7 @@ int windNinjaCLI(int argc, char* argv[]) casefile.setIsZipOpen(true); casefile.setCaseZipFile(zipFile); + casefile.openCaseZipFile(); std::ofstream mainCaseCfgFILE(mainCaseCfgFile); if (!mainCaseCfgFILE) @@ -2059,6 +2060,7 @@ int windNinjaCLI(int argc, char* argv[]) cout << "ERROR: The simulations returned a bad value.\n"; return -1; } + casefile.closeCaseZipFile(); } catch (badForecastFile& e ) { //catch a badForecastFile From 9f250c8dcb65e57349dd5c7836a30ffe2fcf3626 Mon Sep 17 00:00:00 2001 From: latwood Date: Wed, 2 Apr 2025 19:47:53 -0600 Subject: [PATCH 30/35] continuing first pass of casefile GDAL zipping methods. For issue #7 rearranged casefile functions a bunch, to now only allow zip file renaming AFTER all the files have been added to it, in an attempt to avoid windows zip renaming problems now runs fine for the windows build, other than the issues, really need to find a windows equivalent for . Need to do some additional testing and cleanup of the casefile GDAL zipping methods before moving on though. --- src/gui/mainWindow.cpp | 2 +- src/ninja/casefile.cpp | 94 +++++++++++++++++++++++++++++------------ src/ninja/casefile.h | 15 ++++--- src/ninja/cli.cpp | 2 +- src/ninja/ninja.cpp | 2 +- src/ninja/ninjafoam.cpp | 2 +- 6 files changed, 80 insertions(+), 37 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index f8506530..cfdfafb6 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1701,7 +1701,6 @@ int mainWindow::solve() std::ofstream mainCaseCfgFILE; if (writeCF) { - casefile.setIsZipOpen(true); casefile.setCaseZipFile(zipFile); casefile.openCaseZipFile(); mainCaseCfgFILE.open(mainCaseCfgFile); @@ -3204,6 +3203,7 @@ int mainWindow::solve() try { ninjaSuccess = army->startRuns( nThreads ); casefile.closeCaseZipFile(); + casefile.renameCaseZipFile(); } catch (bad_alloc& e) { diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 4df231ea..7cdb583e 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -4,68 +4,98 @@ std::mutex zipMutex; CaseFile::CaseFile() { - isZipOpen = false; caseZipFile = ""; + finalCaseZipFile = ""; + isZipOpen = false; zipHandle = NULL; -} -void CaseFile::setIsZipOpen(bool isZippOpen) -{ - isZipOpen = isZippOpen; -} - -bool CaseFile::getIsZipOpen() -{ - return isZipOpen; + setCaseZipFileCount = 0; } void CaseFile::setCaseZipFile(std::string caseZippFile) { + if (setCaseZipFileCount > 0) + { + CPLError(CE_Failure, CPLE_FileIO, "not allowed to run setCaseZipFile() twice on the same CaseFile instance!!!"); + } + caseZipFile = caseZippFile; + finalCaseZipFile = caseZippFile; + setCaseZipFileCount++; } -std::string CaseFile::getCaseZipFile() +void CaseFile::updateCaseZipFile(std::string newCaseZipFile) { - return caseZipFile; + if (setCaseZipFileCount == 0) + { + CPLError(CE_Failure, CPLE_FileIO, "updateCaseZipFile() called before setCaseZipFile()!!!"); + } + + // only updates the first time that there is a difference, use the first input newCaseZipFile instance for the final caseZipFile name + // this should only occur for the first run/ninja + if (strcmp( caseZipFile.c_str(), finalCaseZipFile.c_str() ) == 0) + { + finalCaseZipFile = newCaseZipFile; + } } -// to avoid renaming the casefile except for the first run/ninja, checking for a specific starting zip file name -void CaseFile::renameCaseZipFile(std::string newCaseZipFile) +void CaseFile::renameCaseZipFile() { - if (strcmp( CPLGetFilename( caseZipFile.c_str() ), "tmp.ninja" ) == 0) + if (isZipOpen == true) + { + CPLError(CE_Failure, CPLE_FileIO, "renameCaseZipFile() called on a still open zip file: %s", caseZipFile.c_str()); + } + + if (strcmp( caseZipFile.c_str(), finalCaseZipFile.c_str() ) != 0) { - //closeCaseZipFile(); - //std::replace(caseZipFile.begin(),caseZipFile.end(), '\\', '/'); - //std::replace(newCaseZipFile.begin(),newCaseZipFile.end(), '\\', '/'); - if (VSIRename(caseZipFile.c_str(), newCaseZipFile.c_str()) == 0) + if (VSIRename(caseZipFile.c_str(), finalCaseZipFile.c_str()) == 0) { - CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", caseZipFile.c_str(), newCaseZipFile.c_str()); - //printf("ZIP_RENAME: Successfully renamed %s to %s\n", caseZipFile.c_str(), newCaseZipFile.c_str()); - caseZipFile = newCaseZipFile; + //CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", caseZipFile.c_str(), finalCaseZipFile.c_str()); + printf("ZIP_RENAME: Successfully renamed %s to %s\n", caseZipFile.c_str(), finalCaseZipFile.c_str()); + caseZipFile = finalCaseZipFile; } else { - CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", caseZipFile.c_str(), newCaseZipFile.c_str()); + CPLError(CE_Failure, CPLE_FileIO, "Failed to rename %s to %s", caseZipFile.c_str(), finalCaseZipFile.c_str()); } - //openCaseZipFile(); } } void CaseFile::openCaseZipFile() { - //bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); -std::cout << "openingCaseZipFile" << std::endl; + std::cout << "openingCaseZipFile" << std::endl; + + if (isZipOpen == true) + { + CPLError(CE_Failure, CPLE_FileIO, "Running openCaseZipFile() on already open zip file: %s", caseZipFile.c_str()); + } + + bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); + if (doesZipExist == true) + { + printf("warning: zip file %s already exists, replacing zip", caseZipFile.c_str()); + VSIUnlink( caseZipFile.c_str() ); + } + zipHandle = CPLCreateZip(caseZipFile.c_str(), NULL); if (zipHandle == NULL) { CPLError(CE_Failure, CPLE_FileIO, "Failed to create or open zip file: %s", caseZipFile.c_str()); } + isZipOpen = true; } void CaseFile::closeCaseZipFile() { -std::cout << "closingCaseZipFile" << std::endl; + std::cout << "closingCaseZipFile" << std::endl; + + if (isZipOpen == false) + { + CPLError(CE_Failure, CPLE_FileIO, "Running closeCaseZipFile() on an unopened zip file: %s", caseZipFile.c_str()); + } + CPLCloseZip(zipHandle); zipHandle = NULL; + isZipOpen = false; } void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd) @@ -161,6 +191,16 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st } } +bool CaseFile::getIsZipOpen() +{ + return isZipOpen; +} + +std::string CaseFile::getCaseZipFile() +{ + return caseZipFile; +} + std::string CaseFile::getCurrentTime() { const boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 723d2932..948f8cfc 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -42,26 +42,29 @@ class CaseFile private: - bool isZipOpen; std::string caseZipFile; + std::string finalCaseZipFile; + bool isZipOpen; void* zipHandle; + int setCaseZipFileCount; + public: CaseFile(); - void setIsZipOpen(bool isZippOpen); - bool getIsZipOpen(); - void setCaseZipFile(std::string caseZippFile); - std::string getCaseZipFile(); - void renameCaseZipFile(std::string newCaseZipFile); + void updateCaseZipFile(std::string newCaseZipFile); + void renameCaseZipFile(); void openCaseZipFile(); void closeCaseZipFile(); void addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd); + bool getIsZipOpen(); + std::string getCaseZipFile(); + std::string getCurrentTime(); std::string convertDateTimeToStd(const boost::local_time::local_date_time& ninjaTime); diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index fbec1a06..79beed72 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -465,7 +465,6 @@ int windNinjaCLI(int argc, char* argv[]) std::string mainCaseCfgFilename = "config.cfg"; std::string mainCaseCfgFile = CPLFormFilename(outputDir.c_str(), mainCaseCfgFilename.c_str(), ""); - casefile.setIsZipOpen(true); casefile.setCaseZipFile(zipFile); casefile.openCaseZipFile(); @@ -2061,6 +2060,7 @@ int windNinjaCLI(int argc, char* argv[]) return -1; } casefile.closeCaseZipFile(); + casefile.renameCaseZipFile(); } catch (badForecastFile& e ) { //catch a badForecastFile diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index 4e0a8244..c560cb01 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2858,7 +2858,7 @@ void ninja::writeOutputFiles() std::string volVtkSurfFile = CPLFormFilename(directoryofVTK.c_str(), volVtkSurfFilename.c_str(), ""); if( casefile->getIsZipOpen() ) { - casefile->renameCaseZipFile(casefilename); + casefile->updateCaseZipFile(casefilename); std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 96254c79..7026394d 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -3659,7 +3659,7 @@ void NinjaFoam::writeMassMeshVtkOutput() std::string volVtkSurfFile = CPLFormFilename(directoryofVTK.c_str(), volVtkSurfFilename.c_str(), ""); if( casefile->getIsZipOpen() ) { - casefile->renameCaseZipFile(casefilename); + casefile->updateCaseZipFile(casefilename); std::string timestr = ""; if( input.ninjaTime.is_not_a_date_time() ) From 06ad18d34a3ddcc7cf8eff5125167715f3d5a137 Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 3 Apr 2025 15:16:17 -0600 Subject: [PATCH 31/35] found and fixed an error causing momentum solver multi runs with vtk and/or casefile output from failing after the first run seems like this was broken since adding in the massMeshVtk output methods, but luckily it wasn't added as a generic method for all users till we made vtk output standard in the momentum solver related to issue #7 --- src/ninja/ninjafoam.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index 7026394d..d4648cb9 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -4220,7 +4220,7 @@ void NinjaFoam::SetMeshResolutionAndResampleDem() { // need to setup mesh sizing BEFORE the dem gets resampled, but AFTER the mesh resolution gets set massMesh.set_numVertLayers(20); // done in cli.cpp calling ninja_army calling ninja calling this function, with windsim.setNumVertLayers( i_, 20); where i_ is ninjaIdx - massMesh.set_meshResolution(meshResolution, meshResolutionUnits); + massMesh.set_meshResolution(meshResolution, lengthUnits::meters); massMesh.compute_domain_height(input); } From af601991d01e22f597ce05efa7e118d68ca62606 Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 3 Apr 2025 15:26:45 -0600 Subject: [PATCH 32/35] more correct fix to momentum solver multi runs with vtk and/or casefile output --- src/ninja/ninjafoam.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index d4648cb9..f3831d25 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -4164,7 +4164,7 @@ void NinjaFoam::SetMeshResolutionAndResampleDem() h = s.substr(pos+18, pos+23); } - meshResolution = atof(h.c_str()); + set_meshResolution( atof(h.c_str()), lengthUnits::meters ); } //otherwise, if the mesh resolution hasn't been set, calculate it else if(meshResolution < 0.0){ @@ -4220,7 +4220,7 @@ void NinjaFoam::SetMeshResolutionAndResampleDem() { // need to setup mesh sizing BEFORE the dem gets resampled, but AFTER the mesh resolution gets set massMesh.set_numVertLayers(20); // done in cli.cpp calling ninja_army calling ninja calling this function, with windsim.setNumVertLayers( i_, 20); where i_ is ninjaIdx - massMesh.set_meshResolution(meshResolution, lengthUnits::meters); + massMesh.set_meshResolution(meshResolution, meshResolutionUnits); massMesh.compute_domain_height(input); } From b959c68062fef0c9af36f821aabe7c3c87df2733 Mon Sep 17 00:00:00 2001 From: latwood Date: Thu, 3 Apr 2025 15:33:57 -0600 Subject: [PATCH 33/35] figured out the windows replacement to the library use in casefile, OpenMP omp_lock_t, which turned out to already be present all over in the WindNinja code. For issue #7 I think that this was required and works, because various ninjas were running in parallel, each trying to access and add file data to the same casefile zip file all at the same time with this fix, as well as the last one, I tested the casefile methods like crazy on both Windows and Ubuntu. The casefile methods now work quite well in all the different kinds of ways, on both windows and Ubuntu. --- src/ninja/casefile.cpp | 7 ++++--- src/ninja/casefile.h | 10 +++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 7cdb583e..7aa6b110 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -1,7 +1,5 @@ #include "casefile.h" -std::mutex zipMutex; - CaseFile::CaseFile() { caseZipFile = ""; @@ -100,7 +98,10 @@ void CaseFile::closeCaseZipFile() void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd) { - std::lock_guard lock(zipMutex); // for multithreading issue + // Acquire a lock for the multithreading issue, to protect the non-thread safe zip read and write process +#ifdef _OPENMP + omp_guard netCDF_guard(netCDF_lock); +#endif try { bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 948f8cfc..761b502e 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -33,10 +33,18 @@ #include #include #include -#include #include #include +#ifdef _OPENMP +#include +#include "omp_guard.h" +#endif // #ifdef _OPENMP + +#ifdef _OPENMP +extern omp_lock_t netCDF_lock; +#endif // #ifdef _OPENMP + class CaseFile { From 1b18c4243d20648cfdb0f7e494ecc24c55d8b345 Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 7 Apr 2025 17:58:44 -0600 Subject: [PATCH 34/35] final cleanup of casefile stuff, for issue #7 amongst other cleanup, renamed zip files "_ninja.zip" instead of ".ninja", windows required renaming the zip files adding on a ".zip" to access and use the zip files, seemed better to just have the files already in that format rather than forcing the user to mess with the file naming --- src/gui/mainWindow.cpp | 33 ++++++++++-------- src/ninja/casefile.cpp | 77 +++++++++++++++++++---------------------- src/ninja/casefile.h | 8 ++--- src/ninja/cli.cpp | 17 +++++---- src/ninja/ninja.cpp | 17 +++++---- src/ninja/ninjafoam.cpp | 17 +++++---- 6 files changed, 83 insertions(+), 86 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index cfdfafb6..8c50fa5b 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1686,14 +1686,16 @@ int mainWindow::solve() setCursor(Qt::ArrowCursor); //Restart everything return false; } - //std::replace(outputDir.begin(),outputDir.end(), '/', '\\'); + #ifdef WIN32 + std::replace(outputDir.begin(),outputDir.end(), '/', '\\'); + #endif bool writeCF = tree->solve->CaseFileBox->isChecked(); CaseFile casefile; - std::string zipFile = CPLFormFilename(outputDir.c_str(), "tmp", "ninja"); + std::string zipFile = CPLFormFilename(outputDir.c_str(), "tmp_ninja", "zip"); std::string mainCaseCfgFilename = "config.cfg"; std::string mainCaseCfgFile = CPLFormFilename(outputDir.c_str(), mainCaseCfgFilename.c_str(), ""); @@ -2449,8 +2451,8 @@ int mainWindow::solve() { pointFilename = CPLFormFilename(CPLGetFilename(pointPath.c_str()), pointFilename.c_str(), ""); } - std::string pointZipPathFile = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); - casefile.addFileToZip(pointZipPathFile, pointFile); + std::string pointZipEntry = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); + casefile.addFileToZip(pointZipEntry, pointFile); } // setup list of actually used/selected stations std::string selectedStationsFilename = "selected_stations.csv"; @@ -2482,8 +2484,8 @@ int mainWindow::solve() selectedStationsFILE << pointFilename << "\n"; } selectedStationsFILE.close(); - std::string selectedStationsZipPathFile = CPLFormFilename("PointInitialization", selectedStationsFilename.c_str(), ""); - casefile.addFileToZip(selectedStationsZipPathFile, selectedStationsFile); + std::string selectedStationsZipEntry = CPLFormFilename("PointInitialization", selectedStationsFilename.c_str(), ""); + casefile.addFileToZip(selectedStationsZipEntry, selectedStationsFile); VSIUnlink( selectedStationsFile.c_str() ); } // if (writeCF) @@ -2820,8 +2822,8 @@ int mainWindow::solve() mainCaseCfgFILE << "--forecast_times " << outstr << "\n"; mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); - std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); - casefile.addFileToZip(weatherZipPathFile, weatherFile); + std::string weatherZipEntry = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); + casefile.addFileToZip(weatherZipEntry, weatherFile); } // if (writeCF && times.size() > 0) try @@ -2898,8 +2900,8 @@ int mainWindow::solve() mainCaseCfgFILE << "--forecast_times " << outstr << "\n"; mainCaseCfgFILE << "--forecast_filename " << weatherFile << "\n"; std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); - std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); - casefile.addFileToZip(weatherZipPathFile, weatherFile); + std::string weatherZipEntry = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); + casefile.addFileToZip(weatherZipEntry, weatherFile); } // if (writeCF && times.size() == 0) nRuns = army->getSize(); @@ -3132,8 +3134,8 @@ int mainWindow::solve() if (initMethod == WindNinjaInputs::domainAverageInitializationFlag) { domainRunFILE.close(); - std::string domainRunZipPathFile = CPLFormFilename("DomainAverageInitialization", domainRunCfgFilename.c_str(), ""); - casefile.addFileToZip(domainRunZipPathFile, domainRunCfgFile ); + std::string domainRunZipEntry = CPLFormFilename("DomainAverageInitialization", domainRunCfgFilename.c_str(), ""); + casefile.addFileToZip(domainRunZipEntry, domainRunCfgFile ); VSIUnlink( domainRunCfgFile.c_str() ); } } @@ -3202,8 +3204,11 @@ int mainWindow::solve() //start the army try { ninjaSuccess = army->startRuns( nThreads ); - casefile.closeCaseZipFile(); - casefile.renameCaseZipFile(); + if( casefile.getIsZipOpen() ) + { + casefile.closeCaseZipFile(); + casefile.renameCaseZipFile(); + } } catch (bad_alloc& e) { diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 7aa6b110..9e6dcb61 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -6,27 +6,24 @@ CaseFile::CaseFile() finalCaseZipFile = ""; isZipOpen = false; zipHandle = NULL; - - setCaseZipFileCount = 0; } void CaseFile::setCaseZipFile(std::string caseZippFile) { - if (setCaseZipFileCount > 0) + if (caseZipFile != "") { - CPLError(CE_Failure, CPLE_FileIO, "not allowed to run setCaseZipFile() twice on the same CaseFile instance!!!"); + throw std::runtime_error("not allowed to run setCaseZipFile() twice on the same CaseFile instance!!!"); } caseZipFile = caseZippFile; finalCaseZipFile = caseZippFile; - setCaseZipFileCount++; } void CaseFile::updateCaseZipFile(std::string newCaseZipFile) { - if (setCaseZipFileCount == 0) + if (caseZipFile == "") { - CPLError(CE_Failure, CPLE_FileIO, "updateCaseZipFile() called before setCaseZipFile()!!!"); + throw std::runtime_error("updateCaseZipFile() called before setCaseZipFile()!!!"); } // only updates the first time that there is a difference, use the first input newCaseZipFile instance for the final caseZipFile name @@ -41,15 +38,14 @@ void CaseFile::renameCaseZipFile() { if (isZipOpen == true) { - CPLError(CE_Failure, CPLE_FileIO, "renameCaseZipFile() called on a still open zip file: %s", caseZipFile.c_str()); + throw std::runtime_error("renameCaseZipFile() called on a still open zip file!!!"); } if (strcmp( caseZipFile.c_str(), finalCaseZipFile.c_str() ) != 0) { if (VSIRename(caseZipFile.c_str(), finalCaseZipFile.c_str()) == 0) { - //CPLDebug("ZIP_RENAME", "Successfully renamed %s to %s", caseZipFile.c_str(), finalCaseZipFile.c_str()); - printf("ZIP_RENAME: Successfully renamed %s to %s\n", caseZipFile.c_str(), finalCaseZipFile.c_str()); + CPLDebug("NINJA", "Successfully renamed %s to %s", caseZipFile.c_str(), finalCaseZipFile.c_str()); caseZipFile = finalCaseZipFile; } else { @@ -60,35 +56,35 @@ void CaseFile::renameCaseZipFile() void CaseFile::openCaseZipFile() { - std::cout << "openingCaseZipFile" << std::endl; + CPLDebug("NINJA", "opening case zip file %s", caseZipFile.c_str()); if (isZipOpen == true) { - CPLError(CE_Failure, CPLE_FileIO, "Running openCaseZipFile() on already open zip file: %s", caseZipFile.c_str()); + throw std::runtime_error("openCaseZipFile() called on already open zip file!!! " + caseZipFile); } bool doesZipExist = CPLCheckForFile((char*)caseZipFile.c_str(), NULL); if (doesZipExist == true) { - printf("warning: zip file %s already exists, replacing zip", caseZipFile.c_str()); + printf("WARNING: zip file %s already exists, replacing zip\n", caseZipFile.c_str()); VSIUnlink( caseZipFile.c_str() ); } zipHandle = CPLCreateZip(caseZipFile.c_str(), NULL); if (zipHandle == NULL) { - CPLError(CE_Failure, CPLE_FileIO, "Failed to create or open zip file: %s", caseZipFile.c_str()); + throw std::runtime_error("Failed to create or open zip file!!! " + caseZipFile); } isZipOpen = true; } void CaseFile::closeCaseZipFile() { - std::cout << "closingCaseZipFile" << std::endl; + CPLDebug("NINJA", "closing case zip file %s", caseZipFile.c_str()); if (isZipOpen == false) { - CPLError(CE_Failure, CPLE_FileIO, "Running closeCaseZipFile() on an unopened zip file: %s", caseZipFile.c_str()); + throw std::runtime_error("closeCaseZipFile() called on an unopened zip file!!! " + caseZipFile); } CPLCloseZip(zipHandle); @@ -96,7 +92,7 @@ void CaseFile::closeCaseZipFile() isZipOpen = false; } -void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd) +void CaseFile::addFileToZip(const std::string& zipEntry, const std::string& fileToAdd) { // Acquire a lock for the multithreading issue, to protect the non-thread safe zip read and write process #ifdef _OPENMP @@ -127,68 +123,65 @@ void CaseFile::addFileToZip(const std::string& withinZipPathedFilename, const st } // read in the file data to be copied to the zip - VSILFILE *file = VSIFOpenL(fileToAdd.c_str(), "rb"); - if (file == nullptr) + VSILFILE *FILE = VSIFOpenL(fileToAdd.c_str(), "rb"); + if (FILE == nullptr) { CPLError(CE_Failure, CPLE_FileIO, "Could not open file for reading with VSIL: %s", fileToAdd.c_str()); - closeCaseZipFile(); return; } - VSIFSeekL(file, 0, SEEK_END); - vsi_l_offset fileSize = VSIFTellL(file); - VSIFSeekL(file, 0, SEEK_SET); // rather than VSIRewindL(file);? + VSIFSeekL(FILE, 0, SEEK_END); + vsi_l_offset fileSize = VSIFTellL(FILE); + VSIFSeekL(FILE, 0, SEEK_SET); // rather than VSIRewindL(FILE);? char *data = (char*)CPLMalloc(fileSize); if (data == nullptr) { CPLError(CE_Failure, CPLE_FileIO, "Failed to allocate memory for file data."); - VSIFCloseL(file); - closeCaseZipFile(); + VSIFCloseL(FILE); return; } - if (VSIFReadL(data, 1, fileSize, file) != fileSize) + if (VSIFReadL(data, 1, fileSize, FILE) != fileSize) { CPLError(CE_Failure, CPLE_FileIO, "Failed to read file contents: %s", fileToAdd.c_str()); CPLFree(data); - VSIFCloseL(file); - closeCaseZipFile(); + VSIFCloseL(FILE); return; } - VSIFCloseL(file); + VSIFCloseL(FILE); // add the file data to the zip - if (CPLCreateFileInZip(zipHandle, withinZipPathedFilename.c_str(), NULL) != CE_None) { - CPLError(CE_Failure, CPLE_FileIO, "Failed to create file in zip: %s", withinZipPathedFilename.c_str()); + if (CPLCreateFileInZip(zipHandle, zipEntry.c_str(), NULL) != CE_None) + { + CPLError(CE_Failure, CPLE_FileIO, "Failed to create file in zip: %s", zipEntry.c_str()); CPLFree(data); - CPLCloseZip(zipHandle); return; } - if (CPLWriteFileInZip(zipHandle, data, static_cast(fileSize)) != CE_None) { - CPLError(CE_Failure, CPLE_FileIO, "Failed to write data to file in zip: %s", withinZipPathedFilename.c_str()); + if (CPLWriteFileInZip(zipHandle, data, static_cast(fileSize)) != CE_None) + { + CPLError(CE_Failure, CPLE_FileIO, "Failed to write data to file in zip: %s", zipEntry.c_str()); CPLFree(data); - CPLCloseZip(zipHandle); + return; } - if (CPLCloseFileInZip(zipHandle) != CE_None) { - CPLError(CE_Failure, CPLE_FileIO, "Failed to close file in zip: %s", withinZipPathedFilename.c_str()); + if (CPLCloseFileInZip(zipHandle) != CE_None) + { + CPLError(CE_Failure, CPLE_FileIO, "Failed to close file in zip: %s", zipEntry.c_str()); CPLFree(data); - CPLCloseZip(zipHandle); + return; } CPLFree(data); } catch (const std::exception& e) { - CPLDebug("Exception", "Caught exception: %s", e.what()); - CPLError(CE_Failure, CPLE_AppDefined, "Exception caught: %s", e.what()); + CPLError(CE_Failure, CPLE_AppDefined, "Exception caught during casefile addFileToZip(): %s", e.what()); } catch (...) { - CPLDebug("Exception", "Caught unknown exception."); - CPLError(CE_Failure, CPLE_AppDefined, "Caught unknown exception."); + CPLError(CE_Failure, CPLE_AppDefined, "Exception caught during casefile addFileToZip(): Cannot determine exception type."); } } diff --git a/src/ninja/casefile.h b/src/ninja/casefile.h index 761b502e..27f7cdad 100644 --- a/src/ninja/casefile.h +++ b/src/ninja/casefile.h @@ -39,11 +39,11 @@ #ifdef _OPENMP #include #include "omp_guard.h" -#endif // #ifdef _OPENMP +#endif #ifdef _OPENMP extern omp_lock_t netCDF_lock; -#endif // #ifdef _OPENMP +#endif class CaseFile { @@ -55,8 +55,6 @@ class CaseFile bool isZipOpen; void* zipHandle; - int setCaseZipFileCount; - public: CaseFile(); @@ -68,7 +66,7 @@ class CaseFile void openCaseZipFile(); void closeCaseZipFile(); - void addFileToZip(const std::string& withinZipPathedFilename, const std::string& fileToAdd); + void addFileToZip(const std::string& zipEntry, const std::string& fileToAdd); bool getIsZipOpen(); std::string getCaseZipFile(); diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 79beed72..21427192 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -460,7 +460,7 @@ int windNinjaCLI(int argc, char* argv[]) outputDir = CPLGetPath( vm["elevation_file"].as().c_str() ); } - std::string zipFile = CPLFormFilename(outputDir.c_str(), "tmp", "ninja"); + std::string zipFile = CPLFormFilename(outputDir.c_str(), "tmp_ninja", "zip"); std::string mainCaseCfgFilename = "config.cfg"; std::string mainCaseCfgFile = CPLFormFilename(outputDir.c_str(), mainCaseCfgFilename.c_str(), ""); @@ -529,8 +529,8 @@ int windNinjaCLI(int argc, char* argv[]) { std::string weatherFile = vm["forecast_filename"].as(); std::string weatherFilename = CPLGetFilename( weatherFile.c_str() ); - std::string weatherZipPathFile = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); - casefile.addFileToZip(weatherZipPathFile, weatherFile); + std::string weatherZipEntry = CPLFormFilename("WxModelInitialization", weatherFilename.c_str(), ""); + casefile.addFileToZip(weatherZipEntry, weatherFile); } if (vm.count("wx_station_filename")) { @@ -541,8 +541,8 @@ int windNinjaCLI(int argc, char* argv[]) { pointFilename = CPLFormFilename(CPLGetFilename(pointPath.c_str()), pointFilename.c_str(), ""); } - std::string pointZipPathFile = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); - casefile.addFileToZip(pointZipPathFile, pointFile); + std::string pointZipEntry = CPLFormFilename("PointInitialization", pointFilename.c_str(), ""); + casefile.addFileToZip(pointZipEntry, pointFile); } } @@ -2059,8 +2059,11 @@ int windNinjaCLI(int argc, char* argv[]) cout << "ERROR: The simulations returned a bad value.\n"; return -1; } - casefile.closeCaseZipFile(); - casefile.renameCaseZipFile(); + if( casefile.getIsZipOpen() ) + { + casefile.closeCaseZipFile(); + casefile.renameCaseZipFile(); + } } catch (badForecastFile& e ) { //catch a badForecastFile diff --git a/src/ninja/ninja.cpp b/src/ninja/ninja.cpp index c560cb01..90ed11f3 100644 --- a/src/ninja/ninja.cpp +++ b/src/ninja/ninja.cpp @@ -2852,10 +2852,9 @@ void ninja::writeOutputFiles() } volVTK VTK(u, v, w, mesh.XORD, mesh.YORD, mesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), mesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string volVtkFilename = CPLGetFilename( input.volVTKFile.c_str() ); - std::string directoryofVTK = CPLGetPath( input.volVTKFile.c_str() ); - std::string volVtkSurfFilename = volVtkFilename.substr(0, volVtkFilename.length() - 4) + "_surf.vtk"; - std::string volVtkSurfFile = CPLFormFilename(directoryofVTK.c_str(), volVtkSurfFilename.c_str(), ""); + std::string volVtkFilename = CPLGetFilename(input.volVTKFile.c_str()); + std::string volVtkSurfFilename = CPLSPrintf("%s_surf.vtk",CPLGetBasename(input.volVTKFile.c_str())); + std::string volVtkSurfFile = CPLFormFilename(CPLGetPath(input.volVTKFile.c_str()), volVtkSurfFilename.c_str(), ""); if( casefile->getIsZipOpen() ) { casefile->updateCaseZipFile(casefilename); @@ -2869,10 +2868,10 @@ void ninja::writeOutputFiles() timestr = casefile->convertDateTimeToStd(input.ninjaTime); } - std::string volVtkZipPathFile = CPLFormFilename(timestr.c_str(), volVtkFilename.c_str(), ""); - casefile->addFileToZip(volVtkZipPathFile, input.volVTKFile); - std::string volVtkSurfZipPathFile = CPLFormFilename(timestr.c_str(), volVtkSurfFilename.c_str(), ""); - casefile->addFileToZip(volVtkSurfZipPathFile, volVtkSurfFile); + std::string volVtkZipEntry = CPLFormFilename(timestr.c_str(), volVtkFilename.c_str(), ""); + casefile->addFileToZip(volVtkZipEntry, input.volVTKFile); + std::string volVtkSurfZipEntry = CPLFormFilename(timestr.c_str(), volVtkSurfFilename.c_str(), ""); + casefile->addFileToZip(volVtkSurfZipEntry, volVtkSurfFile); } if( input.volVTKOutFlag == false ) @@ -5078,7 +5077,7 @@ void ninja::set_outputFilenames(double& meshResolution, pdf_fileAppend = os_pdf.str(); - casefilename = rootFile + case_fileAppend + ".ninja"; + casefilename = rootFile + case_fileAppend + "_ninja.zip"; input.kmlFile = rootFile + kmz_fileAppend + ".kml"; input.kmzFile = rootFile + kmz_fileAppend + ".kmz"; diff --git a/src/ninja/ninjafoam.cpp b/src/ninja/ninjafoam.cpp index f3831d25..307ea29a 100644 --- a/src/ninja/ninjafoam.cpp +++ b/src/ninja/ninjafoam.cpp @@ -3307,7 +3307,7 @@ void NinjaFoam::SetOutputFilenames() ascii_fileAppend = os_ascii.str(); pdf_fileAppend = os_pdf.str(); - casefilename = rootFile + case_fileAppend + ".ninja"; + casefilename = rootFile + case_fileAppend + "_ninja.zip"; input.kmlFile = rootFile + kmz_fileAppend + ".kml"; input.kmzFile = rootFile + kmz_fileAppend + ".kmz"; @@ -3653,10 +3653,9 @@ void NinjaFoam::writeMassMeshVtkOutput() } volVTK VTK(massMesh_u, massMesh_v, massMesh_w, massMesh.XORD, massMesh.YORD, massMesh.ZORD, input.dem.get_xllCorner(), input.dem.get_yllCorner(), input.dem.get_nCols(), input.dem.get_nRows(), massMesh.nlayers, input.volVTKFile, vtkWriteFormat, vtk_out_as_utm); - std::string volVtkFilename = CPLGetFilename( input.volVTKFile.c_str() ); - std::string directoryofVTK = CPLGetPath( input.volVTKFile.c_str() ); - std::string volVtkSurfFilename = volVtkFilename.substr(0, volVtkFilename.length() - 4) + "_surf.vtk"; - std::string volVtkSurfFile = CPLFormFilename(directoryofVTK.c_str(), volVtkSurfFilename.c_str(), ""); + std::string volVtkFilename = CPLGetFilename(input.volVTKFile.c_str()); + std::string volVtkSurfFilename = CPLSPrintf("%s_surf.vtk",CPLGetBasename(input.volVTKFile.c_str())); + std::string volVtkSurfFile = CPLFormFilename(CPLGetPath(input.volVTKFile.c_str()), volVtkSurfFilename.c_str(), ""); if( casefile->getIsZipOpen() ) { casefile->updateCaseZipFile(casefilename); @@ -3670,10 +3669,10 @@ void NinjaFoam::writeMassMeshVtkOutput() timestr = casefile->convertDateTimeToStd(input.ninjaTime); } - std::string volVtkZipPathFile = CPLFormFilename(timestr.c_str(), volVtkFilename.c_str(), ""); - casefile->addFileToZip(volVtkZipPathFile, input.volVTKFile); - std::string volVtkSurfZipPathFile = CPLFormFilename(timestr.c_str(), volVtkSurfFilename.c_str(), ""); - casefile->addFileToZip(volVtkSurfZipPathFile, volVtkSurfFile); + std::string volVtkZipEntry = CPLFormFilename(timestr.c_str(), volVtkFilename.c_str(), ""); + casefile->addFileToZip(volVtkZipEntry, input.volVTKFile); + std::string volVtkSurfZipEntry = CPLFormFilename(timestr.c_str(), volVtkSurfFilename.c_str(), ""); + casefile->addFileToZip(volVtkSurfZipEntry, volVtkSurfFile); } if( input.volVTKOutFlag == false ) From 00948fdca3c0025e67fa8a60932753a61c3e3a51 Mon Sep 17 00:00:00 2001 From: latwood Date: Mon, 7 Apr 2025 18:46:07 -0600 Subject: [PATCH 35/35] more final casefile cleanup, initial attempt to better handle closing the zip file at every return, throw, exit instance. The gui seems like it is good to go, seems to be working correctly even when clicking cancel now, but the cli might need some more of this. For issue #7 --- src/gui/mainWindow.cpp | 24 +++++++++++++++++++----- src/ninja/casefile.cpp | 14 ++++++-------- src/ninja/cli.cpp | 23 +++++++++++++---------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 8c50fa5b..f05b6387 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -1872,6 +1872,7 @@ int mainWindow::solve() progressDialog->cancel(); disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); + casefile.closeCaseZipFile(); return false; } @@ -2242,6 +2243,7 @@ int mainWindow::solve() progressDialog->cancel(); disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); + casefile.closeCaseZipFile(); return false; } } @@ -2470,6 +2472,7 @@ int mainWindow::solve() disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); //Restart everything delete army; + casefile.closeCaseZipFile(); return false; } for( size_t pIdx = 0; pIdx < pointFileList.size(); pIdx++ ) @@ -2553,6 +2556,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; }catch(...) { //catch all exceptions and tell the user, prevent segfaults @@ -2568,6 +2572,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; } nRuns = army->getSize(); @@ -2626,6 +2631,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; }catch(...) { //catch any and all exceptions and tell the user @@ -2641,6 +2647,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; } nRuns = army->getSize(); @@ -2676,6 +2683,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; }catch(...) { //catch any and all exceptions and tell the user @@ -2691,6 +2699,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; } nRuns = army->getSize(); @@ -2713,6 +2722,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; } @@ -2783,6 +2793,7 @@ int mainWindow::solve() setCursor(Qt::ArrowCursor); tree->weather->checkForModelData(); progressDialog->cancel(); + casefile.closeCaseZipFile(); return false; } @@ -2845,6 +2856,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; } catch (...) { QMessageBox::critical( @@ -2859,6 +2871,7 @@ int mainWindow::solve() progressDialog->cancel(); progressDialog->hide(); delete army; + casefile.closeCaseZipFile(); return false; } @@ -3204,11 +3217,8 @@ int mainWindow::solve() //start the army try { ninjaSuccess = army->startRuns( nThreads ); - if( casefile.getIsZipOpen() ) - { - casefile.closeCaseZipFile(); - casefile.renameCaseZipFile(); - } + casefile.closeCaseZipFile(); + casefile.renameCaseZipFile(); } catch (bad_alloc& e) { @@ -3220,6 +3230,7 @@ int mainWindow::solve() disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); delete army; + casefile.closeCaseZipFile(); return false; } catch (cancelledByUser& e) @@ -3231,6 +3242,7 @@ int mainWindow::solve() disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); delete army; + casefile.closeCaseZipFile(); return false; } catch (exception& e) @@ -3242,6 +3254,7 @@ int mainWindow::solve() disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); delete army; + casefile.closeCaseZipFile(); return false; } catch (...) @@ -3253,6 +3266,7 @@ int mainWindow::solve() disconnect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelSolve())); setCursor(Qt::ArrowCursor); delete army; + casefile.closeCaseZipFile(); return false; } diff --git a/src/ninja/casefile.cpp b/src/ninja/casefile.cpp index 9e6dcb61..a7d3b19e 100644 --- a/src/ninja/casefile.cpp +++ b/src/ninja/casefile.cpp @@ -80,16 +80,14 @@ void CaseFile::openCaseZipFile() void CaseFile::closeCaseZipFile() { - CPLDebug("NINJA", "closing case zip file %s", caseZipFile.c_str()); - - if (isZipOpen == false) + // just skip if called on an unopened zip file, makes shutting WindNinja down unexpectedly easier to do + if (isZipOpen == true) { - throw std::runtime_error("closeCaseZipFile() called on an unopened zip file!!! " + caseZipFile); + CPLDebug("NINJA", "closing case zip file %s", caseZipFile.c_str()); + CPLCloseZip(zipHandle); + zipHandle = NULL; + isZipOpen = false; } - - CPLCloseZip(zipHandle); - zipHandle = NULL; - isZipOpen = false; } void CaseFile::addFileToZip(const std::string& zipEntry, const std::string& fileToAdd) diff --git a/src/ninja/cli.cpp b/src/ninja/cli.cpp index 21427192..c6ee9ec3 100644 --- a/src/ninja/cli.cpp +++ b/src/ninja/cli.cpp @@ -161,8 +161,10 @@ int windNinjaCLI(int argc, char* argv[]) bool writeParsed = false; bool writeValues = false; + CaseFile casefile; + //initializeOptions(); - + // Moved to initializeOptions() try { // Declare a group of options that will be @@ -443,8 +445,7 @@ int windNinjaCLI(int argc, char* argv[]) } } - //helper for casefile output of CLI - CaseFile casefile; + // helper for casefile output of CLI if (vm["write_casefile"].as() == true) { std::string outputDir = vm.count("output_path") ? vm["output_path"].as().c_str() : ""; @@ -2057,31 +2058,33 @@ int windNinjaCLI(int argc, char* argv[]) if(!windsim.startRuns(vm["num_threads"].as())) { cout << "ERROR: The simulations returned a bad value.\n"; - return -1; - } - if( casefile.getIsZipOpen() ) - { casefile.closeCaseZipFile(); - casefile.renameCaseZipFile(); + return -1; } + casefile.closeCaseZipFile(); + casefile.renameCaseZipFile(); } - catch (badForecastFile& e - ) { //catch a badForecastFile + catch (badForecastFile& e) + { //catch a badForecastFile cout << "Exception badForecastFile caught: " << e.what() << "\n"; cout << "There was a problem downloading the forecast file or it had bad data.\n"; + casefile.closeCaseZipFile(); return -1; }catch (bad_alloc& e) { cout << "Exception bad_alloc caught: " << e.what() << endl; cout << "WindNinja appears to have run out of memory." << endl; + casefile.closeCaseZipFile(); return -1; }catch (exception& e) { cout << "Exception caught: " << e.what() << endl; + casefile.closeCaseZipFile(); return -1; }catch (...) { cout << "Exception caught: Cannot determine exception type." << endl; + casefile.closeCaseZipFile(); return -1; }