From ca7a892397061e9e7cc288fdddf8c15867637e30 Mon Sep 17 00:00:00 2001 From: Federico Guerra Date: Sun, 4 Aug 2024 10:33:49 +0000 Subject: [PATCH] [Add] WOSS Release 1.13.0 --- CHANGELOG | 7 + configure.ac | 2 +- doxy/Mainpage.dox | 17 +- samples/test_aloha_with_dbs.tcl | 2 +- tests/Makefile.am | 4 +- tests/woss-bellhop-test.cpp | 262 ++++++ tests/woss-test.cpp | 33 +- tests/woss-test.h | 890 +++++++++++++++++- woss/ac-toolbox-arr-asc-reader.cpp | 24 +- woss/ac-toolbox-arr-asc-reader.h | 16 +- woss/ac-toolbox-arr-bin-reader.cpp | 44 +- woss/ac-toolbox-arr-bin-reader.h | 15 +- woss/ac-toolbox-shd-reader.cpp | 447 +++++++-- woss/ac-toolbox-shd-reader.h | 166 +++- woss/bellhop-woss.cpp | 6 +- woss/res-reader.h | 9 +- woss/woss-manager-simple.h | 24 +- woss/woss-manager.cpp | 3 +- woss/woss-manager.h | 7 +- woss/woss_db/res-pressure-bin-db-creator.cpp | 2 + woss/woss_db/res-pressure-txt-db-creator.cpp | 7 +- woss/woss_db/res-pressure-txt-db.cpp | 3 +- woss/woss_db/woss-db-manager.cpp | 195 +++- woss/woss_db/woss-db-manager.h | 50 +- woss/woss_def/pressure-definitions.h | 15 +- .../woss_def/random-generator-definitions.cpp | 4 +- 26 files changed, 2062 insertions(+), 192 deletions(-) create mode 100644 tests/woss-bellhop-test.cpp diff --git a/CHANGELOG b/CHANGELOG index df36926..49d07fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -156,3 +156,10 @@ v1.12.6 - fixed gcc-13 warnings - TCL examples updated to GEBCO 2023 - removed warning in woss::BellhopWoss - changed URL of main WOSS website + +v1.13.0 - Added support for SSP NetCDF4 databases generated from WOA2023 dataset + - added bellhop autotools test unit + - improved the WossTest framework + - woss::ResReader fixed importing of bellhop's SPL and arrivals from binary mode + - woss::WossDbManager - added support for importing bathymetry, SSP and sediment from a string + - woss::WossManager - added API to erase all WOSS instances diff --git a/configure.ac b/configure.ac index ff243b8..2761215 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,7 @@ # whose support is gratefully acknowledged. -AC_INIT([WOSS], [1.12.6], [woss@guerra-tlc.com]) +AC_INIT([WOSS], [1.13.0], [woss@guerra-tlc.com]) AM_INIT_AUTOMAKE([foreign subdir-objects]) AC_MSG_NOTICE([WOSS AC_PACKAGE_VERSION]) diff --git a/doxy/Mainpage.dox b/doxy/Mainpage.dox index d0c6c00..94fca4c 100644 --- a/doxy/Mainpage.dox +++ b/doxy/Mainpage.dox @@ -3,7 +3,7 @@ * * @author Federico Guerra - federico@guerra-tlc.com * - * @version 1.12.6 + * @version 1.13.0 * * This document provides a short techical description of the World Ocean Simulation System (WOSS) library * and of its integration into Multi InteRfAce Cross Layer Extension (NS-Miracle).

@@ -153,7 +153,7 @@ * woss::BellhopCreator]; *

  • interface implementation and custom NetCDF db of monthly averaged SSPs, * calculated with the TEOS-10 exact formula [6] based on the temperature, salinity and depth data taken - * from the World Ocean Atlas database of 2001 [7], 2005 [8], 2009 [9], 2013 [10] and 2018 [11] + * from the World Ocean Atlas database of 2001 [7], 2005 [8], 2009 [9], 2013 [10], 2018 [11] and 2023 [12] * [woss::SspWoa2005Db, woss::SspWoa2005DbCreator]; *
  • interface implementation for the GEBCO NetCDF bathymetry databases * (all versions: 1D, 2D, 2008, 2014, 2019, 2020, 2021, 2022) [12], [woss::BathyGebcoDb, woss::BathyGebcoDbCreator]; @@ -185,6 +185,7 @@ *
  • World Ocean Atlas 2009, https://www.nodc.noaa.gov/OC5/WOA09/pr_woa09.html . *
  • World Ocean Atlas 2013, https://www.nodc.noaa.gov/OC5/woa13/ . *
  • World Ocean Atlas 2018, https://www.nodc.noaa.gov/OC5/woa18/ . + *
  • World Ocean Atlas 2023, https://www.nodc.noaa.gov/OC5/woa23/ . *
  • General bathymetric chart of the oceans, http://www.gebco.net . *
  • National geophysical data center, seafloor surficial sediment descriptions, * http://www.ngdc.noaa.gov/mgg/geology/deck41.html . @@ -231,7 +232,7 @@ * @see woss::SSP, woss::SspWoa2005Db, woss::SspWoa2005DbCreator * * - * \section ssp_db_2013 World Ocean Atlas 2001, 2013 and 2018 SSP Databases + * \section ssp_db_2013 World Ocean Atlas 2001, 2013, 2018 and 2023 SSP Databases * * These databases contain monthly, seasonal and annual average of sound speed profiles, calculated with the TEOS-10 * exact formula, and based on the depth, temperature and salinity provided by the World Ocean Atlas. @@ -1319,7 +1320,15 @@ *
  • TCL examples updated to GEBCO 2023 *
  • removed warning in woss::BellhopWoss *
  • changed URL of main WOSS website - +* +*
  • v.1.13.0 * **/ diff --git a/samples/test_aloha_with_dbs.tcl b/samples/test_aloha_with_dbs.tcl index 94f34f1..68c6e5d 100644 --- a/samples/test_aloha_with_dbs.tcl +++ b/samples/test_aloha_with_dbs.tcl @@ -173,7 +173,7 @@ WOSS/Creator/Database/NetCDF/SSP/WOA2013/MonthlyAverage set debug 0 WOSS/Creator/Database/NetCDF/SSP/WOA2013/MonthlyAverage set woss_db_debug 0 set db_ssp [new "WOSS/Creator/Database/NetCDF/SSP/WOA2013/MonthlyAverage"] -$db_ssp setDbPathName "${opt(db_path)}/ssp/WOA2018/WOA2018_SSP_June.nc" +$db_ssp setDbPathName "${opt(db_path)}/ssp/WOA2023/WOA2023_SSP_July.nc" WOSS/Creator/Database/NetCDF/Bathymetry/GEBCO set debug 0 diff --git a/tests/Makefile.am b/tests/Makefile.am index 4702c92..fbfe446 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -34,7 +34,7 @@ LDADD = @NETCDF_LIBADD@ @NETCDF4_LIBADD@ @UW_WOSS_LIBADD@ @UW_WOSS_PHY_LIBADD@ #TEST_EXTENSIONS = .sh # These are the tests programs. -TESTPROGRAMS = woss-coord-definitions-test-bin +TESTPROGRAMS = woss-coord-definitions-test-bin woss-bellhop-test-bin if NETCDF_BUILD #TESTPROGRAMS += @@ -48,6 +48,8 @@ TESTS = $(TESTPROGRAMS) # Here's the source code for the programs. woss_coord_definitions_test_bin_SOURCES = woss-test.cpp woss-coord-definitions-test.cpp +woss_bellhop_test_bin_SOURCES = woss-test.cpp woss-bellhop-test.cpp + EXTRA_DIST = woss-test.h # Cleaning up files created during the process. diff --git a/tests/woss-bellhop-test.cpp b/tests/woss-bellhop-test.cpp new file mode 100644 index 0000000..326d52f --- /dev/null +++ b/tests/woss-bellhop-test.cpp @@ -0,0 +1,262 @@ +/* WOSS - World Ocean Simulation System - + * + * Copyright (C) 2024 Federico Guerra + * and regents of the SIGNET lab, University of Padova + * + * Author: Federico Guerra - federico@guerra-tlc.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This software has been developed by Federico Guerra and SIGNET lab, + * University of Padova, in collaboration with the NATO Centre for + * Maritime Research and Experimentation (http://www.cmre.nato.int ; + * E-mail: pao@cmre.nato.int), whose support is gratefully acknowledged. + */ + + +/** + * @file woss-bellhop-test.cpp + * @author Federico Guerra + * + * \brief + * + * + */ + + +#include +#include +#include "woss-test.h" + +using namespace std; +using namespace woss; + +class WossBellhopTest : public WossTest { + + public: + + WossBellhopTest(); + + virtual ~WossBellhopTest() {} + + void setTxCoordZVector(vector& tx) { + tx_coordz_vector.clear(); tx_coordz_vector = tx; } + + void setRxCoordZVector(vector& rx) { + rx_coordz_vector.clear(); rx_coordz_vector = rx; } + + private: + + virtual void doConfig(); + + virtual void doInit(); + + virtual void doRun(); + + vector tx_coordz_vector; + + vector rx_coordz_vector; + + vector frequencies_vector; + + string db_path; + + string res_path; + +}; + +WossBellhopTest::WossBellhopTest() +: WossTest(), + tx_coordz_vector(), + rx_coordz_vector(), + frequencies_vector(), + db_path(), + res_path("./bh_test_out/") +{ + +} + +void WossBellhopTest::doConfig() { + setWossTestDebug(false); + + setWossRandomGenStream(1); + + setResDbCreatorDebug(false); + setResDbDebug(false); + setResDbUseBinary(false); + setResDbUseTimeArr(false); + setResDbUsePressure(false); + setResDbFilePath(res_path); + setResDbFileName("bh_test.bin"); + + setWossDbManagerDebug(false); + + //db_path = ""; + + if (db_path != "") { + setSedimDeck41DbType(DECK41_DB_V2_TYPE); + setSedimDbCoordFilePath(db_path + "/seafloor_sediment/DECK41_V2_coordinates.nc"); + setSedimDbMarsdenFilePath(db_path + "seafloor_sediment/DECK41_V2_marsden_square.nc"); + setSedimDbMarsdenOneFilePath(db_path + "seafloor_sediment/DECK41_V2_marsden_one_degree.nc"); + + setSspDbFilePath(db_path + "/ssp/WOA2018/WOA2018_SSP_June.nc"); + setSspWoaDbType(WOA_DB_TYPE_2013); + + setBathyDbFilePath(db_path + "bathymetry/GEBCO_2023.nc"); + setBathyDbGebcoFormat(GEBCO_2D_15_SECONDS_BATHY_TYPE); + } + + //setWossBellhopPath(); + setWossCreatorDebug(false); + setWossWorkDirPath(res_path); + setWossClearWorkDir(true); + setWossDebug(false); + setWossSimTime(SimTime(Time(1, 8, 2018), Time(1, 8, 2018))); + setWossEvolutionTimeQuantum(-1.0); + setWossTotalRuns(1); + setWossFrequencyStep(0.0); + setWossTotalRangeSteps(50.0); + setWossTxMinDepthOffset(0.0); + setWossTxMaxDepthOffset(0.0); + setWossTotalTransmitters(1); + setWossTotalRxDepths(1); + setWossRxMinDepthOffset(0.0); + setWossRxMaxDepthOffset(0.0); + setWossTotalRxRanges(1); + setWossRxMinRangeOffset(0.0); + setWossRxMaxRangeOffset(0.0); + setWossTotalRays(2000); + setWossMinAngle(-75.0); + setWossMaxAngle(75.0); + setWossUseThorpeAtt(true); + setWossSspDepthPrecision(1.0E-8); + setWossNormalizedSspDepthSteps(100000); + setWossBellhopMode("a"); + setWossBellhopBeamOptions("B"); + setWossBellhopBathyType("L"); + setWossBellhopBathyMethod("S"); + setWossBellhopAltimType("L"); + setWossBellhopArraySyntax(BELLHOP_CREATOR_ARR_FILE_SYNTAX_2); + setWossBellhopShdSyntax(BELLHOP_CREATOR_SHD_FILE_SYNTAX_1); + setWossBoxDepth(-3000.0); + setWossBoxRange(-3000.0); + + setWossManagerDebug(false); + setWossManagerTimeEvoActive(false); + setWossManagerThreads(0.0); + setWossManagerSpaceSampling(0.0); + setWossManagerUseMultiThread(true); + + tx_coordz_vector.push_back(CoordZ(42.59, 10.125, 80.0)); + rx_coordz_vector.push_back(CoordZ(42.59, 10.1615, 1.0)); + for (int i = 0; i < 25; ++i) + { + frequencies_vector.push_back(500.0 + i*1000.0); + } +} + +void WossBellhopTest::doInit() { + if (db_path == "") { + woss_db_manager->setCustomBathymetry("5|0.0|100.0|100.0|200.0|300.0|150.0|400.0|100.0|700.0|300.0", CoordZ(42.59, 10.125, 80.0)); + woss_db_manager->setCustomSediment("TestSediment|1560.0|200.0|1.5|0.9|0.8|300.0"); + woss_db_manager->setCustomSSP("12|0|1508.42|10|1508.02|20|1507.71|30|1507.53|50|1507.03|75|1507.56|100|1508.08|125|1508.49|150|1508.91|200|1509.75|250|1510.58|300|1511.42"); + } +} + + +void WossBellhopTest::doRun() { + WossManager* curr_woss_manager = woss_controller->getWossManager(); + + for (vector< CoordZ >::iterator it = tx_coordz_vector.begin(); it != tx_coordz_vector.end(); ++it) { + for (vector< CoordZ >::iterator it2 = rx_coordz_vector.begin(); it2 != rx_coordz_vector.end(); ++it2) { + for (vector< double >::iterator it3 = frequencies_vector.begin(); it3 != frequencies_vector.end(); ++it3 ) { + if (debug) { + cout << endl << endl; + cout << "tx coordz = " << (*it) << endl; + cout << "rx coordz = " << (*it2) << endl; + cout << "freq = " << (*it3) << endl; + } + // we need to erase the current woss in order to run it again with different setting + curr_woss_manager->eraseAllWoss(); + bellhop_creator->setBhMode("A"); + bellhop_creator->setWrkDirPath(res_path + "arr_asc/"); + + TimeArr* curr_time_arr_asc = curr_woss_manager->getWossTimeArr((*it), (*it2), (*it3), (*it3)); + + if (curr_time_arr_asc == NULL) { + throw WOSS_EXCEPTION(WOSS_ERROR_OUT_OF_MEMORY); + } + + Pressure* press_temp_asc = SDefHandler::instance()->getPressure()->create( *curr_time_arr_asc ); + + if (press_temp_asc == NULL) { + throw WOSS_EXCEPTION(WOSS_ERROR_OUT_OF_MEMORY); + } + + // we need to erase the current woss in order to run it again with Pressure setting + curr_woss_manager->eraseAllWoss(); + bellhop_creator->setBhMode("a"); + bellhop_creator->setWrkDirPath(res_path + "arr_bin/"); + + TimeArr* curr_time_arr_bin = curr_woss_manager->getWossTimeArr((*it), (*it2), (*it3), (*it3)); + + if (curr_time_arr_bin == NULL) { + throw WOSS_EXCEPTION(WOSS_ERROR_OUT_OF_MEMORY); + } + + Pressure* press_temp_bin = SDefHandler::instance()->getPressure()->create( *curr_time_arr_bin ); + + if (press_temp_bin == NULL) { + throw WOSS_EXCEPTION(WOSS_ERROR_OUT_OF_MEMORY); + } + + if ( abs(press_temp_bin->getTxLossDb() - press_temp_asc->getTxLossDb()) > 1.0) { + throw WOSS_EXCEPTION(WOSS_ERROR_OUT_OF_RANGE_PARAM); + } + + // we need to erase the current woss in order to run it again with Pressure setting + curr_woss_manager->eraseAllWoss(); + bellhop_creator->setBhMode("C"); + bellhop_creator->setWrkDirPath(res_path + "press_shd/"); + + Pressure* curr_pressure = curr_woss_manager->getWossPressure((*it), (*it2), (*it3), (*it3)); + + if (curr_pressure == NULL) { + throw WOSS_EXCEPTION(WOSS_ERROR_OUT_OF_MEMORY); + } + + if (debug) { + cout << endl; + cout << "curr_time_arr_asc = " << (*curr_time_arr_asc) << endl; + cout << "curr_time_arr_bin = " << (*curr_time_arr_bin) << endl; + cout << "time_arr_asc TL = " << (*press_temp_asc) << endl; + cout << "time_arr_bin TL = " << (*press_temp_bin) << endl; + cout << "curr_pressure = " << (*curr_pressure) << endl; + } + } + } + } +} + + +int main(int argc, char* argv []) +{ + WossBellhopTest* woss_bh_test = new WossBellhopTest(); + woss_bh_test->run(); + delete woss_bh_test; + + return 0; +} diff --git a/tests/woss-test.cpp b/tests/woss-test.cpp index 1c3366a..d6082bb 100644 --- a/tests/woss-test.cpp +++ b/tests/woss-test.cpp @@ -164,7 +164,8 @@ WossTest::WossTest () res_db_creator_debug (WH_DEBUG_DEFAULT), res_db_debug (WH_DEBUG_DEFAULT), res_db_use_binary (true), - res_db_use_time_arr (true), + res_db_use_time_arr (false), + res_db_use_pressure (false), res_db_space_sampling (WH_SPACE_SAMPLING_DEFAULT), res_db_file_path (WH_STRING_DEFAULT), res_db_file_name (WH_STRING_DEFAULT), @@ -216,7 +217,8 @@ WossTest::WossTest () total_rays (WH_TOTAL_RAYS_DEFAULT), min_angle (WH_MIN_ANGLE_DEFAULT), max_angle (WH_MAX_ANGLE_DEFAULT), - spp_depth_precision (WH_SSP_DEPTH_PRECISION_DEFAULT), + use_thorpe_att(true), + ssp_depth_precision (WH_SSP_DEPTH_PRECISION_DEFAULT), normalized_ssp_depth_steps (WH_NORMALIZED_SSP_DEPTH_STEPS_DEFAULT), work_dir_path (WH_WORK_PATH_DEFAULT), bellhop_path (WH_STRING_DEFAULT), @@ -326,6 +328,7 @@ void WossTest::init() { def_handler->setTimeArr (time_arr_proto.clone ()); def_handler->setSSP (ssp_proto.clone ()); random_gen_proto.setSeed (woss_random_gen_stream); + random_gen_proto.initialize (); def_handler->setRandGenerator (random_gen_proto.clone ()); woss_controller = new woss::WossController (); @@ -394,9 +397,10 @@ void WossTest::init() { if (debug) { cout << "Setting TimeArr binary" << endl; } + string name = "arr_bin_" + res_db_file_name; res_db_creator_time_arr_bin = new woss::ResTimeArrBinDbCreator (); - - res_db_creator_time_arr_bin->setDbPathName (res_db_file_path + "/" + res_db_file_name); + + res_db_creator_time_arr_bin->setDbPathName (res_db_file_path + "/" + name); res_db_creator_time_arr_bin->setDebug (res_db_creator_debug); res_db_creator_time_arr_bin->setWossDebug (res_db_debug); @@ -406,33 +410,39 @@ void WossTest::init() { if (debug) { cout << "Setting TimeArr ASCII" << endl; } + string name = "arr_asc_" + res_db_file_name; + res_db_creator_time_arr_txt = new woss::ResTimeArrTxtDbCreator (); - res_db_creator_time_arr_txt->setDbPathName (res_db_file_path + "/" + res_db_file_name); + res_db_creator_time_arr_txt->setDbPathName (res_db_file_path + "/" + name); res_db_creator_time_arr_txt->setDebug (res_db_creator_debug); res_db_creator_time_arr_txt->setWossDebug (res_db_debug); woss_controller->setTimeArrDbCreator (res_db_creator_time_arr_txt); } - else if ( res_db_use_binary == true && res_db_use_time_arr == false ) { + if ( res_db_use_binary == true && res_db_use_pressure == true ) { if (debug) { cout << "Setting Pressure binary" << endl; } + string name = "pres_bin_" + res_db_file_name; + res_db_creator_press_bin = new woss::ResPressureBinDbCreator (); - res_db_creator_press_bin->setDbPathName (res_db_file_path + "/" + res_db_file_name); + res_db_creator_press_bin->setDbPathName (res_db_file_path + "/" + name); res_db_creator_press_bin->setDebug (res_db_creator_debug); res_db_creator_press_bin->setWossDebug (res_db_debug); woss_controller->setPressureDbCreator (res_db_creator_press_bin); } - else if ( res_db_use_binary == false && res_db_use_time_arr == false ) { + else if ( res_db_use_binary == false && res_db_use_pressure == true ) { if (debug) { cout << "Setting Pressure ASCII" << endl; } + string name = "pres_asc" + res_db_file_name; + res_db_creator_press_txt = new woss::ResPressureTxtDbCreator (); - res_db_creator_press_txt->setDbPathName (res_db_file_path + "/" + res_db_file_name); + res_db_creator_press_txt->setDbPathName (res_db_file_path + "/" + name); res_db_creator_press_txt->setDebug (res_db_creator_debug); res_db_creator_press_txt->setWossDebug (res_db_debug); @@ -451,7 +461,7 @@ void WossTest::init() { bellhop_creator->setWrkDirPath (work_dir_path); bellhop_creator->setCleanWorkDir (woss_clear_work_dir); bellhop_creator->setEvolutionTimeQuantum (evolution_time_quantum); - bellhop_creator->setThorpeAttFlag (true); + bellhop_creator->setThorpeAttFlag (use_thorpe_att); bellhop_creator->setTotalRuns (total_runs); bellhop_creator->setFrequencyStep (frequency_step); bellhop_creator->setTotalRangeSteps (total_range_steps); @@ -466,7 +476,8 @@ void WossTest::init() { bellhop_creator->setRxMaxRangeOffset (rx_max_range_offset); bellhop_creator->setRaysNumber (total_rays); bellhop_creator->setAngles (woss::CustomAngles (min_angle, max_angle)); - bellhop_creator->setSspDepthPrecision (spp_depth_precision); + bellhop_creator->setThorpeAttFlag (use_thorpe_att); + bellhop_creator->setSspDepthPrecision (ssp_depth_precision); bellhop_creator->setSspDepthSteps (normalized_ssp_depth_steps); bellhop_creator->setBellhopPath (bellhop_path); bellhop_creator->setBhMode (bellhop_mode); diff --git a/tests/woss-test.h b/tests/woss-test.h index 8c087be..5d4f5a8 100644 --- a/tests/woss-test.h +++ b/tests/woss-test.h @@ -286,6 +286,890 @@ namespace woss { **/ void run(); + /** + * Sets the WossTest object debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossTestDebug(bool flag) { debug = flag; return *this; } + + /** + * gets the WossTest object debug flag + * @return debug flag + **/ + bool getWossTestDebug() const { return debug; } + + + /** + * Sets the woss::RandomGenerator stream/seed value + * @param stream seed/stream value + * @return reference to this instance + **/ + WossTest& setWossRandomGenStream(int stream) { woss_random_gen_stream = stream; return *this;} + + /** + * Gets the woss::RandomGenerator stream/seed value + * @return seed/stream value + **/ + int getWossRandomGenStream() const { return woss_random_gen_stream; } + + + /** + * Sets the Result Db Creator debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setResDbCreatorDebug(bool flag) { res_db_creator_debug = flag; return *this; } + + /** + * Gets the Result Db Creator debug flag + * @return debug flag + **/ + bool getResDbCreatorDebug() const { return res_db_creator_debug; } + + /** + * Sets the Result Db debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setResDbDebug(bool flag) { res_db_debug = flag; return *this; } + + /** + * Gets the Result Db debug flag + * @return debug flag + **/ + bool getResDbDebug() const { return res_db_debug; } + + /** + * If set to true, it will use the ResDb binary format classes + * @param flag use binary flag + * @return reference to this instance + **/ + WossTest& setResDbUseBinary(bool flag) { res_db_use_binary = flag; return *this; } + + /** + * Gets the use binary flag + * @return use binary flag + **/ + bool getResDbUseBinary() const { return res_db_use_binary; } + + /** + * If set to true, it will use the ResDb TimeArrival format classes + * If set to false, it will use the ResDb Pressure format classes + * @param flag use TimeArrival flag + * @return reference to this instance + **/ + WossTest& setResDbUseTimeArr(bool flag) { res_db_use_time_arr = flag; return *this; } + + /** + * Gets the time arrival flag + * @return use TimeArrival flag + **/ + bool getResDbUseTimeArr() const { return res_db_use_time_arr; } + + /** + * If set to true, it will use the ResDb Pressure format classes + * If set to false, it will use the ResDb Pressure format classes + * @param flag use Pressure flag + * @return reference to this instance + **/ + WossTest& setResDbUsePressure(bool flag) { res_db_use_pressure = flag; return *this; } + + /** + * Gets the res db pressure flag + * @return use Pressure flag + **/ + bool getResDbUsePressure() const { return res_db_use_pressure; } + + /** + * Sets the ResDb's space sampling + * @param sampling space sampling in [m] + * @return reference to this instance + **/ + WossTest& setResDbSpaceSampling(double sampling) { res_db_space_sampling = sampling; return *this; } + + /** + * Gets the ResDb's space sampling + * @return space sampling in [m] + **/ + double getResDbSpaceSampling() const { return res_db_space_sampling; } + + + /** + * Sets the ResDb'file path + * @param path file path + * @return reference to this instance + **/ + WossTest& setResDbFilePath(const ::std::string& path) { res_db_file_path = path; return *this; } + + /** + * Gets the ResDb'file path + * @return file path + **/ + ::std::string getResDbFilePath() const { return res_db_file_path; } + + /** + * Sets the ResDb file name + * @param path file name + * @return reference to this instance + **/ + WossTest& setResDbFileName(const ::std::string& file_name) { res_db_file_name = file_name; return *this; } + + /** + * Gets the ResDb'file name + * @return file name + **/ + ::std::string getResDbFileName() const { return res_db_file_name; } + + +#if defined (WOSS_NETCDF_SUPPORT) +#if defined (WOSS_NETCDF4_SUPPORT) + /** + * Sets the DECK41DbType db type + * @param type DECK41DbType type + * @return reference to this instance + **/ + WossTest& setSedimDeck41DbType( DECK41DbType type) { sedim_deck41_db_type = type; return *this; } + + /** + * Gets the DECK41DbType db type + * @return DECK41DbType db type + **/ + DECK41DbType getSedimDeck41DbType() const { return sedim_deck41_db_type; } +#endif // defined (WOSS_NETCDF4_SUPPORT) + + /** + * Sets the SedimDeck41DbCreator debug flag + * @param flag debug boolean value + * @return reference to this instance + **/ + WossTest& setSedimDbCreatorDebug( bool flag ) { sedim_db_creator_debug = flag; return *this; } + + /** + * Gets the SedimDeck41DbCreator debug flag + * @return debug boolean value + **/ + bool getSedimDbCreatorDebug() const { return sedim_db_creator_debug; } + + /** + * Sets the Sediment db debug flag + * @param flag debug boolean value + * @return reference to this instance + **/ + WossTest& setSedimDbDebug(bool flag) { sedim_db_debug = flag; return *this; } + + /** + * Gets the Sediment db debug flag + * @return debug boolean value + **/ + bool getSedimDbDebug() const { return sedim_db_debug; } + + /** + * Sets the Sediment DECK41 Db indexed by coordinates + * @param path path to db file + * @return reference to this instance + **/ + WossTest& setSedimDbCoordFilePath(const ::std::string& path) { sedim_db_coord_file_path = path; return *this; } + + /** + * Gets the Sediment DECK41 Db indexed by coordinates path + * @return string containing the file path + **/ + ::std::string getSedimDbCoordFilePath() const { return sedim_db_coord_file_path; } + + /** + * Sets the Sediment DECK41 Db indexed by Marsden square file path + * @param path path to db file + * @return reference to this instance + **/ + WossTest& setSedimDbMarsdenFilePath(const ::std::string& path) { sedim_db_marsden_file_path = path; return *this; } + + /** + * Gets the Sediment DECK41 Db indexed by Marsden squares file path + * @return string containing the file path + **/ + ::std::string getSedimDbMarsdenFilePath() const { return sedim_db_marsden_file_path; } + + /** + * Sets the Sediment DECK41 Db indexed by Marsden one squares file path + * @param path path to db file + * @return reference to this instance + **/ + WossTest& setSedimDbMarsdenOneFilePath(const ::std::string& path) { sedim_db_marsden_one_file_path = path; return *this; } + + /** + * Gets the Sediment DECK41 Db indexed by Marsden one squares file path + * @return string containing the file path + **/ + ::std::string getSedimDbMarsdenOneFilePath() const { return sedim_db_marsden_one_file_path; } + + + /** + * Sets the SspWoa2005DbCreator debug flag + * @param flag debug boolean value + * @return reference to this instance + **/ + WossTest& setSspDbCreatorDebug( bool flag ) { ssp_db_creator_debug = flag; return *this; } + + /** + * Gets the SspWoa2005DbCreator debug flag + * @return boolean debug flag value + **/ + bool getSspDbCreatorDebug() const { return ssp_db_creator_debug; } + + /** + * Sets the SSP Db debug flag + * @param flag debug boolean value + * @return reference to this instance + **/ + WossTest& setSspDbDebug( bool flag ) { ssp_db_debug = flag; return *this; } + + /** + * Gets the Ssp Db debug flag + * @return boolean debug flag value + **/ + bool getSspDbDebug() const { return ssp_db_debug; } + + /** + * Sets the SSP Db file path + * @param path path to db file + * @return reference to this instance + **/ + WossTest& setSspDbFilePath(const ::std::string& path) { ssp_db_file_path = path; return *this; } + + /** + * Gets the SSP Db file path + * @return string containing the path to db file + **/ + ::std::string getSspDbFilePath() const { return ssp_db_file_path; } + +#if defined (WOSS_NETCDF4_SUPPORT) + /** + * Sets the SSP Db WOADbType type + * @param type WOADbType of the db path + * @return reference to this instance + **/ + WossTest& setSspWoaDbType( WOADbType type) { ssp_woa_db_type = type; return *this; } + + /** + * Gets the SSP Db WOADbType type + * @return WOADbType of the db path + **/ + WOADbType getSspWoaDbType() const { return ssp_woa_db_type; } +#endif // defined (WOSS_NETCDF_SUPPORT) + + + /** + * Sets the BathyGebcoDbCreator debug flag + * @param flag debug boolean value + * @return reference to this instance + **/ + WossTest& setBathyDbCreatorDebug( bool flag ) { bathy_db_creator_debug = flag; return *this; } + + /** + * Gets the BathyGebcoDbCreator debug flag + * @return debug boolean value + **/ + bool getBathyDbCreatorDebug() const { return bathy_db_creator_debug; } + + /** + * Sets the Bathy Db debug flag + * @param flag debug boolean value + * @return reference to this instance + **/ + WossTest& setBathyDbDebug( bool flag ) { bathy_db_debug = flag; return *this; } + + /** + * Gets the Bathy Db debug flag + * @return debug boolean value + **/ + bool getBathyDbDebug() const { return bathy_db_debug; } + + /** + * Sets the Bathy Db GEBCO_BATHY_TYPE format type + * @param type GEBCO_BATHY_TYPE of the file db path + * @return reference to this instance + **/ + WossTest& setBathyDbGebcoFormat(GEBCO_BATHY_TYPE type) { bathy_db_gebco_format = type; return *this; } + + /** + * Gets the Bathy Db GEBCO_BATHY_TYPE format type + * @return GEBCO_BATHY_TYPE of the file db path + **/ + GEBCO_BATHY_TYPE getBathyDbGebcoFormat() const { return bathy_db_gebco_format; } + + /** + * Sets the Bathy Db file path + * @param path path to db file + * @return reference to this instance + **/ + WossTest& setBathyDbFilePath(const ::std::string& path) { bathy_db_file_path = path; return *this; } + + /** + * Gets the Bathy Db file path + * @param path path to db file + * @return string containing the path to Bathy Db file + **/ + ::std::string getBathyDbFilePath() const { return bathy_db_file_path; } +#endif // defined (WOSS_NETCDF_SUPPORT) + + + /** + * Sets the WossDbManager debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossDbManagerDebug(bool flag) { woss_db_manager_debug = flag; return *this; } + + /** + * Gets the WossDbManager debug flag + * @return boolean debug flag + **/ + bool getWossDbManagerDebug() const { return woss_db_manager_debug; } + + + /** + * Sets the WossCreator debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossCreatorDebug(bool flag) { woss_creator_debug = flag; return *this; } + + /** + * Gets the WossCreator debug flag + * @return boolean debug flag + **/ + bool getWossCreatorDebug() const { return woss_creator_debug; } + + /** + * Sets the Woss channel simulator debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossDebug(bool flag) { woss_debug = flag; return *this; } + + /** + * Gets the Woss channel simulator debug flag + * @return boolean debug flag + **/ + bool getWossDebug() const { return woss_debug; } + + /** + * Configure if the Woss channel simulator working dir should be freed or kept + * @param flag clean work dir boolean flag + * @return reference to this instance + **/ + WossTest& setWossClearWorkDir(bool flag) { woss_clear_work_dir = flag; return *this; } + + /** + * Gets the Woss clean dir flag., if the Woss channel simulator working dir should be freed or kept + * @return clean work dir boolean flag + **/ + bool getWossClearWorkDir() const { return woss_clear_work_dir; } + + /** + * Configures the Woss channel simulator time quantum to be used by time dependent simulations + * @param time evolution time quantum of the channel model, in [s] + * @return reference to this instance + **/ + WossTest& setWossEvolutionTimeQuantum(double time) { evolution_time_quantum = time; return *this; } + + /** + * Gets the Woss channel simulator time quantum which is used by time dependent simulations + * @return evolution time quantum of the channel model, in [s] + **/ + double getWossEvolutionTimeQuantum() const { return evolution_time_quantum; } + + /** + * Configures the Woss channel simulator total realizations. + * Each run is based on random perturbation of the input data. + * @param runs number of total runs to be executed + * @return reference to this instance + **/ + WossTest& setWossTotalRuns(int runs) { total_runs = runs; return *this; } + + /** + * Gets the Woss channel simulator total realizations number. + * Each run is based on random perturbation of the input data. + * @return number of total runs to be executed + **/ + int getWossTotalRuns() const { return total_runs; } + + /** + * Configures the Woss channel simulator frequencies that should be computed. + * The steps are applied between the start and the end frequencies. + * @param frequency_step frequency step in [hZ] + * @return reference to this instance + **/ + WossTest& setWossFrequencyStep(double step) { frequency_step = step; return *this; } + + /** + * Gets the Woss channel simulator frequencies frequency steps + * @return frequency step in [hZ] + **/ + double getWossFrequencyStep() const { return frequency_step; } + + /** + * Configures the Woss channel simulator range steps that should be used + * The steps are applied between the tx and rx distance. + * @param total_range_steps number of range steps + * @return reference to this instance + **/ + WossTest& setWossTotalRangeSteps(double step) { total_range_steps = step; return *this; } + + /** + * Gets the Woss channel simulator range steps that should be used + * The steps are applied between the tx and rx distance. + * @return number of range steps + **/ + double getWossTotalRangeSteps() const { return total_range_steps; } + + /** + * Configures the Woss channel simulator transmitter minimum depth offset + * @param offset minimum depth offset in [m] + * @return reference to this instance + **/ + WossTest& setWossTxMinDepthOffset(double offset) { tx_min_depth_offset = offset; return *this; } + + /** + * Gets the Woss channel simulator transmitter minimum depth offset + * @return minimum depth offset in [m] + **/ + double getWossTxMinDepthOffset() const { return tx_min_depth_offset; } + + /** + * Configures the Woss channel simulator transmitter maximum depth offset + * @param offset minimum depth offset in [m] + * @return reference to this instance + **/ + WossTest& setWossTxMaxDepthOffset(double offset) { tx_max_depth_offset = offset; return *this; } + + /** + * Gets the Woss channel simulator transmitter maximum depth offset + * @return maximum depth offset in [m] + **/ + double getWossTxMaxDepthOffset() const { return tx_max_depth_offset; } + + /** + * Configures the Woss channel simulator number of transmitters + * @param transmitters number of transmitters + * @return reference to this instance + **/ + WossTest& setWossTotalTransmitters(int transmitters) { total_transmitters = transmitters; return *this; } + + /** + * Gets the Woss channel simulator number of transmitters + * @return number of transmitters + **/ + int getWossTotalTransmitters() const { return total_transmitters; } + + /** + * Configures the Woss channel simulator number of receiver depth points + * @param rx_depths number of receiver depth points + * @return reference to this instance + **/ + WossTest& setWossTotalRxDepths(int rx_depths) { total_rx_depths = rx_depths; return *this; } + + /** + * Gets the Woss channel simulator number of receiver depth points + * @return number of receiver depth points + **/ + int getWossTotalRxDepths() const { return total_rx_depths; } + + /** + * Configures the Woss channel simulator receiver mimimum depth offset + * @param offset receiver mimimum depth offset in [m] + * @return reference to this instance + **/ + WossTest& setWossRxMinDepthOffset(double offset) { rx_min_depth_offset = offset; return *this; } + + /** + * Gets the Woss channel simulator receiver mimimum depth offset + * @return receiver mimimum depth offset in [m] + **/ + double getWossRxMinDepthOffset() const { return rx_min_depth_offset; } + + /** + * Configures the Woss channel simulator receiver maximum depth offset + * @param offset receiver maximum depth offset in [m] + * @return reference to this instance + **/ + WossTest& setWossRxMaxDepthOffset(double offset) { rx_max_depth_offset = offset; return *this; } + + /** + * Gets the Woss channel simulator receiver maximum depth offset + * @return receiver maximum depth offset in [m] + **/ + double getWossRxMaxDepthOffset() const { return rx_max_depth_offset; } + + /** + * Configures the Woss channel simulator receiver number of range points + * @param rx_ranges receiver range point number + * @return reference to this instance + **/ + WossTest& setWossTotalRxRanges(int rx_ranges) { total_rx_ranges = rx_ranges; return *this; } + + /** + * Gets the Woss channel simulator receiver number of range points + * @return receiver range point number + **/ + int getWossTotalRxRanges() const { return total_rx_ranges; } + + /** + * Configures the Woss channel simulator receiver mimimum range offset + * @param offset receiver mimimum range offset [m] + * @return reference to this instance + **/ + WossTest& setWossRxMinRangeOffset(double offset) { rx_min_range_offset = offset; return *this; } + + /** + * Gets the Woss channel simulator receiver mimimum range offset + * @return receiver mimimum range offset [m] + **/ + double getWossRxMinRangeOffset() const { return rx_min_range_offset; } + + /** + * Configures the Woss channel simulator receiver maximum range offset + * @param offset receiver maximum range offset [m] + * @return reference to this instance + **/ + WossTest& setWossRxMaxRangeOffset(double offset) { rx_max_range_offset = offset; return *this; } + + /** + * Gets the Woss channel simulator receiver maximum range offset + * @return receiver maximum range offset [m] + **/ + double getWossRxMaxRangeOffset() const { return rx_max_range_offset; } + + /** + * Configures the Woss channel simulator number of ray traces + * @param rays total number of ray traces + * @return reference to this instance + **/ + WossTest& setWossTotalRays(double rays) { total_rays = rays; return *this; } + + /** + * Gets the Woss channel simulator number of ray traces + * @return total number of ray traces + **/ + double getWossTotalRays() const { return total_rays; } + + /** + * Configures the Woss channel simulator ray tracing mimimum angle + * @param angle ray tracing mimimum angle [decimal degree] + * @return reference to this instance + **/ + WossTest& setWossMinAngle(double angle) { min_angle = angle; return *this; } + + /** + * Gets the Woss channel simulator ray tracing mimimum angle + * @return ray tracing mimimum angle [decimal degree] + **/ + double getWossMinAngle() const { return min_angle; } + + /** + * Configures the Woss channel simulator ray tracing maximum angle + * @param angle ray tracing maximum angle [decimal degree] + * @return reference to this instance + **/ + WossTest& setWossMaxAngle(double angle) { max_angle = angle; return *this; } + + /** + * Gets the Woss channel simulator ray tracing maximum angle + * @return ray tracing maximum angle [decimal degree] + **/ + double getWossMaxAngle() const { return max_angle; } + + /** + * Configures if the Woss channel simulator should add the thorpe attenuation to its computed model + * @param flag add the Thorpe attenuation model + * @return reference to this instance + **/ + WossTest& setWossUseThorpeAtt(bool flag) {use_thorpe_att = flag; return *this; } + + /** + * Gets the Thorpe attenuation model flag + * @return Thorpe attenuation model flag + **/ + bool getWossUseThorpeAtt() const { return use_thorpe_att; } + + /** + * Configures the Woss channel simulator SSP depth precision + * @param precision SSP depth precision in [m] + * @return reference to this instance + **/ + WossTest& setWossSspDepthPrecision(double precision) { ssp_depth_precision = precision; return *this; } + + /** + * Gets the Woss channel simulator SSP depth precision + * @param precision SSP depth precision in [m] + * @return reference to this instance + **/ + double getWossSspDepthPrecision() const { return ssp_depth_precision; } + + /** + * Configures the Woss channel simulator number normalized SSP depth + * @param steps normalized SSP depth steps + * @return reference to this instance + **/ + WossTest& setWossNormalizedSspDepthSteps( double steps ) { normalized_ssp_depth_steps = steps; return *this; } + + /** + * Gets the Woss channel simulator normalized depth steps + * @return normalized SSP depth steps + **/ + double getWossNormalizedSspDepthSteps() const { return normalized_ssp_depth_steps; } + + /** + * Configures the Woss channel simulator work directory path + * @param path path of the work directory + * @return reference to this instance + **/ + WossTest& setWossWorkDirPath(const ::std::string& path) { work_dir_path = path; return *this; } + + /** + * Gets the Woss channel simulator work directory path + * @return a string containing the path of the work directory + **/ + ::std::string getWossWorkDirPath() const { return work_dir_path; } + + /** + * Configures the Woss channel bellhop executable file path + * @param path bellhop executable file path + * @return reference to this instance + **/ + WossTest& setWossBellhopPath(const ::std::string& path) { bellhop_path = path; return *this; } + + /** + * Gets the Woss channel simulator bellhop executable file path + * @return a string containing the path of the bellhop executable file + **/ + ::std::string getWossBellhopPath() const { return bellhop_path; } + + /** + * Configures the Woss channel bellhop running mode + * @param mode bellhop running mode + * @return reference to this instance + **/ + WossTest& setWossBellhopMode(const ::std::string& mode) { bellhop_mode = mode; return *this; } + + /** + * Gets the Woss channel simulator bellhop running mode + * @return bellhop running mode + **/ + ::std::string getWossBellhopMode() const { return bellhop_mode; } + + /** + * Configures the Woss channel bellhop beam options + * @param mode bellhop beam options + * @return reference to this instance + **/ + WossTest& setWossBellhopBeamOptions(const ::std::string& options) { bellhop_beam_options = options; return *this; } + + /** + * Gets the Woss channel simulator bellhop beam options + * @return bellhop beam options + **/ + ::std::string getWossBellhopBeamOptions() const { return bellhop_beam_options; } + + /** + * Configures the Woss channel bellhop bathymetry type + * @param mode bellhop bathymetry type + * @return reference to this instance + **/ + WossTest& setWossBellhopBathyType(const ::std::string& type) { bellhop_bathy_type = type; return *this; } + + /** + * Gets the Woss channel simulator bellhop bathymetry type + * @return bellhop bathymetry type + **/ + ::std::string getWossBellhopBathyType() const { return bellhop_bathy_type; } + + /** + * Configures the Woss channel bellhop bathymetry method + * @param mode bellhop bathymetry method + * @return reference to this instance + **/ + WossTest& setWossBellhopBathyMethod(const ::std::string& type) { bellhop_bathy_method = type; return *this; } + + /** + * Gets the Woss channel simulator bellhop bathymetry method + * @return bellhop bathymetry method + **/ + ::std::string getWossBellhopBathyMethod() const { return bellhop_bathy_method; } + + /** + * Configures the Woss channel bellhop altimetry type + * @param mode bellhop altimetry type + * @return reference to this instance + **/ + WossTest& setWossBellhopAltimType(const ::std::string& type) { bellhop_altim_type = type; return *this; } + + /** + * Gets the Woss channel simulator bellhop altimetry type + * @return bellhop altimetry type + **/ + ::std::string getWossBellhopAltimType() const { return bellhop_altim_type; } + + /** + * Configures the Woss channel bellhop array model result syntax + * @param BellhopArrSyntax bellhop array model result syntax + * @return reference to this instance + **/ + WossTest& setWossBellhopArraySyntax(BellhopArrSyntax syntax) { bellhop_arr_syntax = syntax; return *this; } + + /** + * Gets the Woss channel bellhop array model result syntax + * @return bellhop array model result syntax + **/ + BellhopArrSyntax getWossBellhopArraySyntax() const { return bellhop_arr_syntax; } + + /** + * Configures the Woss channel bellhop pressure model result syntax + * @param BellhopShdSyntax bellhop pressure model result syntax + * @return reference to this instance + **/ + WossTest& setWossBellhopShdSyntax(BellhopShdSyntax syntax) { bellhop_shd_syntax = syntax; return *this; } + + /** + * Gets the Woss channel bellhop pressure model result syntax + * @return bellhop pressure model result syntax + **/ + BellhopShdSyntax getWossBellhopShdSyntax() const { return bellhop_shd_syntax; } + + /** + * Configures the Woss SimTime + * @param time bellhop simulation times + * @return reference to this instance + **/ + WossTest& setWossSimTime(const SimTime& time) { sim_time = time; return *this; } + + /** + * Gets the Woss channel SimTime + * @return simulation times + **/ + SimTime getWossSimTime() const { return sim_time; } + + /** + * Configures the Woss channel simulation box max depth + * @param depth simulation box max depth [m] + * @return reference to this instance + **/ + WossTest& setWossBoxDepth(double depth) { box_depth = depth; return *this; } + + /** + * Gets the Woss channel simulation box max depth + * @return simulation box max depth [m] + **/ + double getWossBoxDepth() const { return box_depth; } + + /** + * Configures the Woss channel simulation box max range + * @param range simulation box max range [m] + * @return reference to this instance + **/ + WossTest& setWossBoxRange(double range) { box_range = range; return *this; } + + /** + * Gets the Woss channel simulation box max range + * @return simulation box max range [m] + **/ + double getWossBoxRange() const { return box_range; } + + + /** + * Configures the WossManager debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossManagerDebug(bool flag) { woss_manager_debug = flag; return *this; } + + /** + * Gets the WossManager debug flag + * @return debug flag + **/ + bool getWossManagerDebug() const { return woss_manager_debug; } + + /** + * Configures the WossManager time evolution feature active + * @param flag time evolution active flag + * @return reference to this instance + **/ + WossTest& setWossManagerTimeEvoActive(bool flag) { time_evolution_active = flag; return *this; } + + /** + * Gets the WossManager time evolution feature active + * @return time evolution active flag + **/ + bool getWossManagerTimeEvoActive() const { return time_evolution_active; } + + /** + * Configures the WossManager number of threads + * @param threads number of threads + * @return reference to this instance + **/ + WossTest& setWossManagerThreads(int threads) { concurrent_threads = threads; return *this; } + + /** + * Gets the WossManager number of threads + * @return number of threads + **/ + int getWossManagerThreads() const { return concurrent_threads; } + + /** + * Configures the WossManager space sampling + * @param sampling space sampling in [m] + * @return reference to this instance + **/ + WossTest& setWossManagerSpaceSampling(double sampling) { woss_manager_space_sampling = sampling; return *this; } + + /** + * Gets the WossManager space sampling + * @return space sampling in [m] + **/ + double getWossManagerSpaceSampling() const { return woss_manager_space_sampling; } + + /** + * Configures the WossManager multithread feature + * @param flag use multithread flag + * @return reference to this instance + **/ + WossTest& setWossManagerUseMultiThread(bool flag) { woss_manager_use_multithread = flag; return *this; } + + /** + * Gets the WossManager multithread flag + * @return use multithread flag + **/ + bool getWossManagerUseMultiThread() const { return woss_manager_use_multithread; } + + + /** + * Configures the WossTransducerHander debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossTransducerHandlerDebug(bool flag) { woss_transducer_handler_debug = flag; return *this; } + + /** + * Gets the WossTransducerHander debug flag + * @return debug flag + **/ + bool getWossTransducerHandlerDebug() const { return woss_transducer_handler_debug; } + + + /** + * Configures the WossController debug flag + * @param flag debug flag + * @return reference to this instance + **/ + WossTest& setWossControllerDebug(bool flag) { woss_controller_debug = flag; return *this; } + + /** + * Gets the WossController debug flag + * @return debug flag + **/ + bool getWossControllerDebug() const { return woss_controller_debug; } + protected: @@ -306,7 +1190,8 @@ namespace woss { bool res_db_creator_debug; //!< enable/disable the debug prints of the woss results database creator. bool res_db_debug; //!< enable/disable the debug prints of the woss result databases. bool res_db_use_binary; //!< set up the woss result database format: binary or textual. - bool res_db_use_time_arr; //!< set up the woss result databases data format: power delay profile or single pressure tap. + bool res_db_use_time_arr; //!< set up the woss result databases data format: power delay profile. + bool res_db_use_pressure; //!< set up the woss result databases data format: single pressure tap. double res_db_space_sampling; //!< set up the woss result database 2D spatial sampling ::std::string res_db_file_path; //!< set up the woss result database file path ::std::string res_db_file_name; //!< set up the woss result database file name (without path) @@ -364,7 +1249,8 @@ namespace woss { double total_rays; //!< woss object configuration: total number of rays (0 = automatic) double min_angle; //!< woss object configuration: minimum vertical angle in decimal degrees double max_angle; //!< woss object configuration: maximum vertical angle in decimal degrees - double spp_depth_precision; //!< woss object configuration: SSP depth precision in meters + bool use_thorpe_att; //!< woss object configuration: use thorpe attenuation in channel computation + double ssp_depth_precision; //!< woss object configuration: SSP depth precision in meters double normalized_ssp_depth_steps; //!< woss object configuration: SSP depth quantization steps ::std::string work_dir_path; //!< woss object configuration: path of the temporary directory ::std::string bellhop_path; //!< woss object configuration: path of the Bellhop executable diff --git a/woss/ac-toolbox-arr-asc-reader.cpp b/woss/ac-toolbox-arr-asc-reader.cpp index 72ad72b..d1a07b5 100644 --- a/woss/ac-toolbox-arr-asc-reader.cpp +++ b/woss/ac-toolbox-arr-asc-reader.cpp @@ -178,10 +178,10 @@ bool ArrAscResReader::getArrAscHeader() { std::string sim_type; // '2D' or '3D' file_reader >> sim_type; - file_reader >> arr_file.frequency; - if(sim_type.compare("'2D'") == 0) { + file_reader >> arr_file.frequency; + //Read in num sources and source depths file_reader >> arr_file.Nsd; arr_file.tx_depths = new float[arr_file.Nsd]; @@ -326,8 +326,9 @@ bool ArrAscResReader::getArrAscFile() { file_reader >> curr_delay; if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_1 || - bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) + bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) { file_reader >> curr_delay_imag; + } file_reader >> curr_src_angle; file_reader >> curr_rx_angle; @@ -340,7 +341,8 @@ bool ArrAscResReader::getArrAscFile() { assert(!::std::isnan(curr_amplitude)); assert(!::std::isinf(curr_amplitude)); assert(!::std::isnan(curr_phase)); assert(!::std::isinf(curr_phase)); assert(!::std::isnan(curr_delay)); assert(!::std::isinf(curr_delay)); //assert(curr_delay >= 0.0); - if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_1 || bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) { + if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_1 + || bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) { assert(!::std::isnan(curr_delay_imag)); assert(!::std::isinf(curr_delay_imag)); //assert(curr_delay_imag >= 0.0); } assert(!::std::isnan(curr_src_angle)); assert(!::std::isinf(curr_src_angle)); @@ -405,24 +407,24 @@ bool ArrAscResReader::getArrAscFile() { } -Pressure* ArrAscResReader::readPressure( double tx_depth, double rx_depth, double rx_range ) const { - return( SDefHandler::instance()->getPressure()->create( *readTimeArr( tx_depth, rx_depth, rx_range ) ) ); +Pressure* ArrAscResReader::readPressure(double frequency, double tx_depth, double rx_depth, double rx_range ) const { + return( SDefHandler::instance()->getPressure()->create( *readTimeArr( frequency, tx_depth, rx_depth, rx_range ) ) ); } -Pressure* ArrAscResReader::readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { +Pressure* ArrAscResReader::readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { if ( !arr_asc_file_collected ) return SDefHandler::instance()->getPressure()->create( Pressure::createNotValid() ); - return( SDefHandler::instance()->getPressure()->create( readMapAvgPressure( tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ) ) ); + return( SDefHandler::instance()->getPressure()->create( readMapAvgPressure( frequency, tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ) ) ); } -TimeArr* ArrAscResReader::readTimeArr( double source_depth, double rx_depth, double rx_range ) const { +TimeArr* ArrAscResReader::readTimeArr( double frequency, double source_depth, double rx_depth, double rx_range ) const { if ( !arr_asc_file_collected ) return( SDefHandler::instance()->getTimeArr()->create( TimeArr::createNotValid() ) ); - return( SDefHandler::instance()->getTimeArr()->create( *accessMap( source_depth,rx_depth,rx_range ) ) ); + return( SDefHandler::instance()->getTimeArr()->create( *accessMap(frequency, source_depth,rx_depth,rx_range ) ) ); } -::std::complex ArrAscResReader::readMapAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { +::std::complex ArrAscResReader::readMapAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { if ( ( last_tx_depth == tx_depth ) && ( last_start_rx_depth == start_rx_depth ) && ( last_start_rx_range == start_rx_range ) && ( last_end_rx_depth == end_rx_depth ) && ( last_end_rx_range == end_rx_range ) ) return last_ret_value; diff --git a/woss/ac-toolbox-arr-asc-reader.h b/woss/ac-toolbox-arr-asc-reader.h index 8ec7a29..4b8d456 100644 --- a/woss/ac-toolbox-arr-asc-reader.h +++ b/woss/ac-toolbox-arr-asc-reader.h @@ -108,7 +108,6 @@ namespace woss { */ float* rx_ranges; - /** * Pointer to an array of TimeArr values [m] */ @@ -180,6 +179,7 @@ namespace woss { /** * Gets the average Pressure value in given rx range-depth box. Returned Pressure is the coherent sum of the computed * average TimeArr + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -187,27 +187,29 @@ namespace woss { * @param end_rx_range end receiver range [m] * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet **/ - virtual Pressure* readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); + virtual Pressure* readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); /** * Gets a Pressure value for given range, depths. Returned Pressure is the coherent sum of the computed * TimeArr + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet **/ - virtual Pressure* readPressure( double tx_depth, double rx_depth, double rx_range ) const; + virtual Pressure* readPressure( double frequency, double tx_depth, double rx_depth, double rx_range ) const; /** * Gets a TimeArr value for given range, depths + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid TimeArr value; a not valid TimeArr if arr_file hasn't been read yet **/ - virtual TimeArr* readTimeArr( double tx_depth, double rx_depth, double rx_range ) const; + virtual TimeArr* readTimeArr( double frequency, double tx_depth, double rx_depth, double rx_range ) const; protected: @@ -254,18 +256,20 @@ namespace woss { /** * Gets the TimeArr value from ArrData TimeArr array associated to given parameters + * @param frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth start receiver depth [m] * @param rx_range start receiver range [m] * @return a valid TimeArr value; a not valid TimeArr if arr_file hasn't been read yet **/ - TimeArr* accessMap( double tx_depth, double rx_depth, double rx_range ) const { + TimeArr* accessMap( double frequency, double tx_depth, double rx_depth, double rx_range ) const { return( arr_file.arr_values + arr_file.getTimeArrIndex( tx_depth, rx_depth, rx_range ) ); } /** * Gets the average Pressure value in given rx range-depth box converted from ArrData TimeArr array + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -273,7 +277,7 @@ namespace woss { * @param end_rx_range end receiver range [m] * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet **/ - ::std::complex readMapAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); + ::std::complex readMapAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); /** diff --git a/woss/ac-toolbox-arr-bin-reader.cpp b/woss/ac-toolbox-arr-bin-reader.cpp index 9626a0f..66b0744 100644 --- a/woss/ac-toolbox-arr-bin-reader.cpp +++ b/woss/ac-toolbox-arr-bin-reader.cpp @@ -115,6 +115,8 @@ bool ArrBinResReader::getArrBinHeader() { return false; } + ::std::cout.precision(WOSS_DECIMAL_PRECISION); + const BellhopWoss* bwoss_ptr = dynamic_cast(woss_ptr); assert( NULL != bwoss_ptr ); @@ -136,16 +138,17 @@ bool ArrBinResReader::getArrBinHeader() { file_reader.ignore(8); // ::std::ios_base::beg; file_reader.read(reinterpret_cast(&arr_file.frequency),sizeof(float)); - file_reader.ignore(8); if(strcmp(sim_type, "'2D'") == 0) { + + file_reader.ignore(8); //Read in num sources and source depths file_reader.read(reinterpret_cast(&arr_file.Nsd),sizeof(int32_t)); arr_file.tx_depths = new float[arr_file.Nsd]; file_reader.read( reinterpret_cast(arr_file.tx_depths), arr_file.Nsd * sizeof(float) ); - file_reader.ignore(8); + file_reader.ignore(8); //Read in num receivers depths and receiver depths file_reader.read(reinterpret_cast(&arr_file.Nrd),sizeof(int32_t)); arr_file.rx_depths = new float[arr_file.Nrd]; @@ -155,7 +158,14 @@ bool ArrBinResReader::getArrBinHeader() { //Read in num receivers ranges and receiver ranges file_reader.read(reinterpret_cast(&arr_file.Nrr),sizeof(int32_t)); arr_file.rx_ranges = new float[arr_file.Nrr]; - file_reader.read( reinterpret_cast(arr_file.rx_ranges), arr_file.Nrr * sizeof(float) ); + + double* rx_ranges_tmp = new double[arr_file.Nrr]; + file_reader.read( reinterpret_cast(rx_ranges_tmp), arr_file.Nrr * sizeof(double) ); + + for (int i = 0; i < arr_file.Nrr; i++) { + arr_file.rx_ranges[i] = (float)rx_ranges_tmp[i]; + } + delete[] rx_ranges_tmp; } else { ::std::cout << "ArrBinResReader(" << woss_ptr->getWossId() @@ -272,8 +282,9 @@ bool ArrBinResReader::getArrBinFile() { file_reader.read( reinterpret_cast(&curr_phase), sizeof(float) ); file_reader.read( reinterpret_cast(&curr_delay), sizeof(float) ); if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_1 || - bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) + bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) { file_reader.read( reinterpret_cast(&curr_delay_imag), sizeof(float) ); + } file_reader.read( reinterpret_cast(&curr_src_angle), sizeof(float) ); file_reader.read( reinterpret_cast(&curr_rx_angle), sizeof(float) ); file_reader.read( reinterpret_cast(&curr_top_bounces), sizeof(float) ); @@ -286,7 +297,8 @@ bool ArrBinResReader::getArrBinFile() { assert(!::std::isnan(curr_amplitude)); assert(!::std::isinf(curr_amplitude)); assert(!::std::isnan(curr_phase)); assert(!::std::isinf(curr_phase)); assert(!::std::isnan(curr_delay)); assert(!::std::isinf(curr_delay)); //assert(curr_delay >= 0.0); - if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_1 || bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) { + if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_1 + || bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_2) { assert(!::std::isnan(curr_delay_imag)); assert(!::std::isinf(curr_delay_imag)); //assert(curr_delay_imag >= 0.0); } assert(!::std::isnan(curr_src_angle)); assert(!::std::isinf(curr_src_angle)); @@ -296,10 +308,12 @@ bool ArrBinResReader::getArrBinFile() { } // GLITCH RECOVERY FROM VERTICAL CHANNEL SIMULATIONS ( HORIZ RANGE == 0, ONLY VERTICAL DEPTH ) - if ( curr_delay <= 0.0 || arr_file.rx_ranges[irr] <= 0.0 ) + if ( curr_delay <= 0.0 || arr_file.rx_ranges[irr] <= 0.0 ) { curr_delay = ( abs( arr_file.rx_depths[ird] - arr_file.tx_depths[isd] ) ) / 1500.0; - if ( curr_delay <= 0.0 ) curr_delay = abs( curr_delay ); - + } + if ( curr_delay <= 0.0 ) { + curr_delay = abs( curr_delay ); + } if (bwoss_ptr->getBellhopArrSyntax() == BELLHOP_CREATOR_ARR_FILE_SYNTAX_0) { curr_pressure_ptr = new Pressure( (curr_amplitude * cos(2.0 * M_PI * arr_file.frequency + curr_phase * M_PI / 180.0) ) , (curr_amplitude * sin(2.0 * M_PI * arr_file.frequency + curr_phase * M_PI / 180.0) ) ); @@ -353,24 +367,24 @@ bool ArrBinResReader::getArrBinFile() { } -Pressure* ArrBinResReader::readPressure( double tx_depth, double rx_depth, double rx_range ) const { - return( SDefHandler::instance()->getPressure()->create( *readTimeArr( tx_depth, rx_depth, rx_range ) ) ); +Pressure* ArrBinResReader::readPressure( double frequency, double tx_depth, double rx_depth, double rx_range ) const { + return( SDefHandler::instance()->getPressure()->create( *readTimeArr( frequency, tx_depth, rx_depth, rx_range ) ) ); } -Pressure* ArrBinResReader::readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { +Pressure* ArrBinResReader::readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { if ( !arr_bin_file_collected ) return SDefHandler::instance()->getPressure()->create( Pressure::createNotValid() ); - return( SDefHandler::instance()->getPressure()->create( readMapAvgPressure( tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ) ) ); + return( SDefHandler::instance()->getPressure()->create( readMapAvgPressure( frequency, tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ) ) ); } -TimeArr* ArrBinResReader::readTimeArr(double source_depth, double rx_depth, double rx_range) const { +TimeArr* ArrBinResReader::readTimeArr(double frequency, double source_depth, double rx_depth, double rx_range) const { if ( !arr_bin_file_collected ) SDefHandler::instance()->getTimeArr()->create( TimeArr::createNotValid() ); - return( SDefHandler::instance()->getTimeArr()->create( *accessMap( source_depth,rx_depth,rx_range ) ) ); + return( SDefHandler::instance()->getTimeArr()->create( *accessMap( frequency, source_depth,rx_depth,rx_range ) ) ); } -::std::complex ArrBinResReader::readMapAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { +::std::complex ArrBinResReader::readMapAvgPressure(double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { if ( ( last_tx_depth == tx_depth ) && ( last_start_rx_depth == start_rx_depth ) && ( last_start_rx_range == start_rx_range ) && ( last_end_rx_depth == end_rx_depth ) && ( last_end_rx_range == end_rx_range ) ) return last_ret_value; diff --git a/woss/ac-toolbox-arr-bin-reader.h b/woss/ac-toolbox-arr-bin-reader.h index 03e5f3c..3c83f0c 100644 --- a/woss/ac-toolbox-arr-bin-reader.h +++ b/woss/ac-toolbox-arr-bin-reader.h @@ -84,6 +84,7 @@ namespace woss { /** * Gets the average Pressure value in given rx range-depth box. Returned Pressure is the coherent sum of the computed * average TimeArr + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -91,27 +92,29 @@ namespace woss { * @param end_rx_range end receiver range [m] * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet **/ - virtual Pressure* readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); + virtual Pressure* readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); /** * Gets a Pressure value for given range, depths. Returned Pressure is the coherent sum of the computed * TimeArr + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet **/ - virtual Pressure* readPressure( double tx_depth, double rx_depth, double rx_range ) const; + virtual Pressure* readPressure(double frequency, double tx_depth, double rx_depth, double rx_range ) const; /** * Gets a TimeArr value for given range, depths + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid TimeArr value; a not valid TimeArr if arr_file hasn't been read yet **/ - virtual TimeArr* readTimeArr( double tx_depth, double rx_depth, double rx_range ) const; + virtual TimeArr* readTimeArr(double frequency, double tx_depth, double rx_depth, double rx_range ) const; protected: @@ -159,17 +162,19 @@ namespace woss { /** * Gets the TimeArr value from ArrData TimeArr array associated to given parameters + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth start receiver depth [m] * @param rx_range start receiver range [m] * @return a valid TimeArr value; a not valid TimeArr if arr_file hasn't been read yet **/ - TimeArr* accessMap(double tx_depth, double rx_depth, double rx_range) const { + TimeArr* accessMap(double frequency, double tx_depth, double rx_depth, double rx_range) const { return( arr_file.arr_values + arr_file.getTimeArrIndex( tx_depth, rx_depth, rx_range ) ); } /** * Gets the average Pressure value in given rx range-depth box converted from ArrStruct TimeArr array + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -177,7 +182,7 @@ namespace woss { * @param end_rx_range end receiver range [m] * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet **/ - ::std::complex readMapAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); + ::std::complex readMapAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); /** diff --git a/woss/ac-toolbox-shd-reader.cpp b/woss/ac-toolbox-shd-reader.cpp index 1115de8..4909a15 100644 --- a/woss/ac-toolbox-shd-reader.cpp +++ b/woss/ac-toolbox-shd-reader.cpp @@ -98,12 +98,79 @@ int ShdData::getPressureIndex( double tx_depth, double rx_depth, double rx_range } +ShdData_v1::ShdData_v1() +: record_length(0), + plot_type(NULL), + frequency(0.0), + Nfreq(0), + frequencies(NULL), + Ntheta(0), + theta(NULL), + Nsd(0), + tx_depths(NULL), + Nrd(0), + rx_depths(NULL), + Nrr(0), + rx_ranges(NULL), + Nrx_per_range(0), + stabil_atten(0.0), + press_values(NULL) +{ + +} + + +int ShdData_v1::getIndex( float value, float* array, int32_t array_size ) const { + if ( value <= array[0] || array_size == 1 ) { + return 0; + } + else if ( value >= array[array_size - 1] ) { + return( array_size - 1 ); + } + else { + double quantized_value = (value - array[0]) / ( ( array[array_size - 1] - array[0] ) / array_size ) ; + if ( ( abs( quantized_value ) - floor( abs( quantized_value ) ) ) >= 0.5 ) return( ceil( quantized_value ) ); + else return( floor( quantized_value ) ); + } +} + + +int ShdData_v1::getIndex( double value, double* array, int32_t array_size ) const { + if ( value <= array[0] || array_size == 1 ) { + return 0; + } + else if ( value >= array[array_size - 1] ) { + return( array_size - 1 ); + } + else { + double quantized_value = (value - array[0]) / ( ( array[array_size - 1] - array[0] ) / array_size ) ; + if ( ( abs( quantized_value ) - floor( abs( quantized_value ) ) ) >= 0.5 ) return( ceil( quantized_value ) ); + else return( floor( quantized_value ) ); + } +} + + +int ShdData_v1::getPressureIndex( double tx_freq, double tx_depth, double rx_depth, double rx_range, double tx_theta ) const { + int freq_index = getIndex( tx_freq, frequencies, Nfreq ); + int theta_index = getIndex( tx_theta, theta, Ntheta ); + int tx_depth_index = getIndex( tx_depth, tx_depths, Nsd ); + int rx_depth_index = getIndex( rx_depth, rx_depths, Nrx_per_range ); + int rx_range_index = getIndex( rx_range/1000.0, rx_ranges, Nrr ); + + return( freq_index * Ntheta * Nsd * Nrx_per_range * Nrr + + theta_index * Nsd * Nrx_per_range * Nrr + + tx_depth_index * Nrx_per_range * Nrr + rx_depth_index * Nrr + + rx_range_index ); +} + + ShdResReader::ShdResReader() : ResReader(), shd_header_collected(false), shd_file_collected(false), file_reader(), shd_file(), + shd_file_v1(), last_tx_depth(SHD_RES_NOT_SET), last_start_rx_depth(SHD_RES_NOT_SET), last_start_rx_range(SHD_RES_NOT_SET), @@ -121,6 +188,7 @@ ShdResReader::ShdResReader( const Woss* const woss ) shd_file_collected(false), file_reader(), shd_file(), + shd_file_v1(), last_tx_depth(SHD_RES_NOT_SET), last_start_rx_depth(SHD_RES_NOT_SET), last_start_rx_range(SHD_RES_NOT_SET), @@ -148,6 +216,9 @@ bool ShdResReader::initialize() { bool ShdResReader::getShdHeader() { if (shd_header_collected == true) return true; + const BellhopWoss* bwoss_ptr = dynamic_cast(woss_ptr); + assert( NULL != bwoss_ptr ); + file_reader.open(file_name.c_str() , ::std::ios::binary|::std::ios::in); if(!file_reader) { @@ -156,74 +227,163 @@ bool ShdResReader::getShdHeader() { return false; } - file_reader.read(reinterpret_cast(&shd_file.record_length),sizeof(int32_t)); + if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_0) { + file_reader.read(reinterpret_cast(&shd_file.record_length),sizeof(int32_t)); - if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() record length = " << shd_file.record_length << ::std::endl; + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() record length = " << shd_file.record_length << ::std::endl; - file_reader.seekg(4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of first record - shd_file.plot_type = new char[10*sizeof(char*)]; - file_reader.read(shd_file.plot_type, 10*sizeof(char*)); + file_reader.seekg(4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of first record + shd_file.plot_type = new char[10*sizeof(char*)]; + file_reader.read(shd_file.plot_type, 10*sizeof(char*)); - if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() plot type : " << shd_file.plot_type << ::std::endl; + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() plot type : " << shd_file.plot_type << ::std::endl; - file_reader.seekg(2*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 2 - file_reader.read(reinterpret_cast(&shd_file.frequency),sizeof(float)); - file_reader.read(reinterpret_cast(&shd_file.Ntheta),sizeof(int32_t)); - file_reader.read(reinterpret_cast(&shd_file.Nsd),sizeof(int32_t)); - file_reader.read(reinterpret_cast(&shd_file.Nrd),sizeof(int32_t)); - file_reader.read(reinterpret_cast(&shd_file.Nrr),sizeof(int32_t)); + file_reader.seekg(2*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 2 - if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Ntheta = " << shd_file.Ntheta - << "; Nsd = " << shd_file.Nsd << "; Nrd = " << shd_file.Nrd << "; Nrr = " << shd_file.Nrr << ::std::endl; + file_reader.read(reinterpret_cast(&shd_file.frequency),sizeof(float)); + file_reader.read(reinterpret_cast(&shd_file.Ntheta),sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file.Nsd),sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file.Nrd),sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file.Nrr),sizeof(int32_t)); - shd_file.theta = new float[shd_file.Ntheta]; - shd_file.tx_depths = new float[shd_file.Nsd]; - shd_file.rx_depths = new float[shd_file.Nrd]; - shd_file.rx_ranges = new float[shd_file.Nrr]; - shd_file.press_values = new ::std::complex[(int)(shd_file.Ntheta * shd_file.Nsd * shd_file.Nrd * shd_file.Nrr)]; + if ( strcmp( shd_file.plot_type, "rectilin " ) == 0) { + shd_file.Nrx_per_range = shd_file.Nrd; + } + else if ( strcmp( shd_file.plot_type, "irregular " ) == 0) { + shd_file.Nrx_per_range = 1; + } + else { + shd_file.Nrx_per_range = shd_file.Nrd; + } - file_reader.seekg(3*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 3 - file_reader.read(reinterpret_cast(shd_file.theta),shd_file.Ntheta*sizeof(float)); + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Ntheta = " << shd_file.Ntheta + << "; Nsd = " << shd_file.Nsd << "; Nrd = " << shd_file.Nrd << "; Nrr = " << shd_file.Nrr + << "; Nrx_range = " << shd_file.Nrx_per_range << ::std::endl; - file_reader.seekg(4*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 4 - file_reader.read(reinterpret_cast(shd_file.tx_depths),shd_file.Nsd*sizeof(float)); + shd_file.theta = new float[shd_file.Ntheta]; + shd_file.tx_depths = new float[shd_file.Nsd]; + shd_file.rx_depths = new float[shd_file.Nrd]; + shd_file.rx_ranges = new float[shd_file.Nrr]; + shd_file.press_values = new ::std::complex[(int)(shd_file.Ntheta * shd_file.Nsd * shd_file.Nrd * shd_file.Nrr)]; - file_reader.seekg(5*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 5 - file_reader.read(reinterpret_cast(shd_file.rx_depths),shd_file.Nrd*sizeof(float)); + file_reader.seekg(3*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 3 + file_reader.read(reinterpret_cast(shd_file.theta),shd_file.Ntheta*sizeof(float)); - file_reader.seekg(6*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 6 - file_reader.read(reinterpret_cast(shd_file.rx_ranges),shd_file.Nrr*sizeof(float)); + file_reader.seekg(4*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 4 + file_reader.read(reinterpret_cast(shd_file.tx_depths),shd_file.Nsd*sizeof(float)); - file_reader.close(); + file_reader.seekg(5*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 5 + file_reader.read(reinterpret_cast(shd_file.rx_depths),shd_file.Nrd*sizeof(float)); + + file_reader.seekg(6*4*shd_file.record_length, ::std::ios_base::beg); //reposition to end of record 6 + file_reader.read(reinterpret_cast(shd_file.rx_ranges),shd_file.Nrr*sizeof(float)); - if (woss_ptr->usingDebug()) { - for (int i = 0; i < shd_file.Ntheta; i++) { + if (woss_ptr->usingDebug()) { + for (int i = 0; i < shd_file.Ntheta; i++) { ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Ntheta(" << i << ") = " << shd_file.theta[i] << ::std::endl; - } + } - for (int i = 0; i < shd_file.Nsd; i++) { + for (int i = 0; i < shd_file.Nsd; i++) { ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Nsd(" << i << ") = " << shd_file.tx_depths[i] << ::std::endl; - } + } - for (int i = 0; i < shd_file.Nrd; i++) { + for (int i = 0; i < shd_file.Nrd; i++) { ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Nrd(" << i << ") = " << shd_file.rx_depths[i] << ::std::endl; - } + } - for (int i = 0; i < shd_file.Nrr; i++) { + for (int i = 0; i < shd_file.Nrr; i++) { ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Nrr(" << i << ") = " << shd_file.rx_ranges[i] << ::std::endl; - } + } + } } + else if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_1) { + file_reader.read(reinterpret_cast(&shd_file_v1.record_length),sizeof(int32_t)); + + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() record length = " << shd_file_v1.record_length << ::std::endl; + + file_reader.seekg(4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of first record + shd_file_v1.plot_type = new char[10*sizeof(char*)]; + file_reader.read(shd_file_v1.plot_type, 10*sizeof(char*)); + + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() plot type : " << shd_file_v1.plot_type << ::std::endl; + + file_reader.seekg(2*4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of record 2 + file_reader.read(reinterpret_cast(&shd_file_v1.Nfreq),sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file_v1.Ntheta),sizeof(int32_t)); + //skip NSx + file_reader.ignore(sizeof(int32_t)); + //Skip NSy + file_reader.ignore(sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file_v1.Nsd),sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file_v1.Nrd),sizeof(int32_t)); + file_reader.read(reinterpret_cast(&shd_file_v1.Nrr),sizeof(int32_t)); + + file_reader.read(reinterpret_cast(&shd_file_v1.frequency),sizeof(double)); + file_reader.read(reinterpret_cast(&shd_file_v1.stabil_atten),sizeof(double)); + + if ( strcmp( shd_file_v1.plot_type, "rectilin " ) == 0) { + shd_file_v1.Nrx_per_range = shd_file_v1.Nrd; + } + else if ( strcmp( shd_file_v1.plot_type, "irregular " ) == 0) { + shd_file_v1.Nrx_per_range = 1; + } + else { + shd_file_v1.Nrx_per_range = shd_file_v1.Nrd; + } - if ( strcmp( shd_file.plot_type, "rectilin " ) == 0) { - shd_file.Nrx_per_range = shd_file.Nrd; - } - else if ( strcmp( shd_file.plot_type, "irregular " ) == 0) { - shd_file.Nrx_per_range = 1; - } - else { - shd_file.Nrx_per_range = shd_file.Nrd; + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() NFreq = " + << shd_file_v1.Nfreq << "; Ntheta = " << shd_file_v1.Ntheta << "; Nsd = " << shd_file_v1.Nsd + << "; Nrd = " << shd_file_v1.Nrd << "; Nrx_rang = " << shd_file_v1.Nrx_per_range << "; Nrr = " << shd_file_v1.Nrr + << "; freq0 = " << shd_file_v1.frequency << "; att = " << shd_file_v1.stabil_atten << ::std::endl; + + shd_file_v1.frequencies = new double[shd_file_v1.Nfreq]; + shd_file_v1.theta = new double[shd_file_v1.Ntheta]; + shd_file_v1.tx_depths = new float[shd_file_v1.Nsd]; + shd_file_v1.rx_depths = new float[shd_file_v1.Nrd]; + shd_file_v1.rx_ranges = new double[shd_file_v1.Nrr]; + shd_file_v1.press_values = new ::std::complex[(int)(shd_file_v1.Nfreq * shd_file_v1.Ntheta * shd_file_v1.Nsd * shd_file_v1.Nrx_per_range * shd_file_v1.Nrr)]; + + file_reader.seekg(3*4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of record 3 + file_reader.read(reinterpret_cast(shd_file_v1.frequencies),shd_file_v1.Nfreq*sizeof(double)); + + file_reader.seekg(4*4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of record 4 + file_reader.read(reinterpret_cast(shd_file_v1.theta),shd_file_v1.Ntheta*sizeof(double)); + + file_reader.seekg(7*4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of record 7 + file_reader.read(reinterpret_cast(shd_file_v1.tx_depths),shd_file_v1.Nsd*sizeof(float)); + + file_reader.seekg(8*4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of record 8 + file_reader.read(reinterpret_cast(shd_file_v1.rx_depths),shd_file_v1.Nrd*sizeof(float)); + + file_reader.seekg(9*4*shd_file_v1.record_length, ::std::ios_base::beg); //reposition to end of record 9 + file_reader.read(reinterpret_cast(shd_file_v1.rx_ranges),shd_file_v1.Nrr*sizeof(double)); + + if (woss_ptr->usingDebug()) { + for (int i = 0; i < shd_file_v1.Nfreq; i++) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() NFreq(" << i << ") = " + << shd_file_v1.frequencies[i] << ::std::endl; + } + + for (int i = 0; i < shd_file_v1.Ntheta; i++) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Ntheta(" << i << ") = " << shd_file_v1.theta[i] << ::std::endl; + } + + for (int i = 0; i < shd_file_v1.Nsd; i++) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Nsd(" << i << ") = " << shd_file_v1.tx_depths[i] << ::std::endl; + } + + for (int i = 0; i < shd_file_v1.Nrd; i++) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Nrd(" << i << ") = " << shd_file_v1.rx_depths[i] << ::std::endl; + } + + for (int i = 0; i < shd_file_v1.Nrr; i++) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdHeader() Nrr(" << i << ") = " << shd_file_v1.rx_ranges[i] << ::std::endl; + } + } } + file_reader.close(); + shd_header_collected = true; return shd_header_collected; @@ -239,105 +399,202 @@ bool ShdResReader::getShdFile() const BellhopWoss* bwoss_ptr = dynamic_cast(woss_ptr); assert( NULL != bwoss_ptr ); - float* press = new float[2*shd_file.Nrr]; - - if (woss_ptr->usingDebug()) + if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() syntax " << (int)bwoss_ptr->getBellhopShdSyntax() << ::std::endl; - for (int itheta = 0; itheta < shd_file.Ntheta; itheta++) { + if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_0) { + float* press = new float[2*shd_file.Nrr]; + + for (int itheta = 0; itheta < shd_file.Ntheta; itheta++) { - for (int isd = 0; isd < shd_file.Nsd; isd++) { + for (int isd = 0; isd < shd_file.Nsd; isd++) { - if (woss_ptr->usingDebug()) - ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() Reading data for source " << isd << " of " - << shd_file.Nsd << ::std::endl; + if (woss_ptr->usingDebug()) + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() Reading data for source " << isd << " of " + << shd_file.Nsd << ::std::endl; - for (int ird = 0; ird < shd_file.Nrd; ird++) { + for (int ird = 0; ird < shd_file.Nrd; ird++) { - int recnum = itheta * shd_file.Nsd * shd_file.Nrx_per_range + isd * shd_file.Nrx_per_range + ird; + int recnum = itheta * shd_file.Nsd * shd_file.Nrx_per_range + isd * shd_file.Nrx_per_range + ird; - if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_0) { recnum += 7; - } - else if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_1) { - recnum += 10; - } - file_reader.seekg( recnum * 4 * shd_file.record_length, ::std::ios_base::beg ); //Move to end of previous record - if ( !file_reader.good()) { - ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() Seek to specified record failed in " - << file_name << ::std::endl; - exit(1); - } - file_reader.read(reinterpret_cast(press), 2*shd_file.Nrr*sizeof(float)); + file_reader.seekg( recnum * 4 * shd_file.record_length, ::std::ios_base::beg ); //Move to end of previous record + if ( !file_reader.good()) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() Seek to specified record failed in " + << file_name << ::std::endl; + exit(1); + } + file_reader.read(reinterpret_cast(press), 2*shd_file.Nrr*sizeof(float)); - for (int i = 0; i < 2*shd_file.Nrr; i += 2 ) { - int press_index = itheta * shd_file.Nsd * shd_file.Nrx_per_range * shd_file.Nrr + isd * shd_file.Nrx_per_range * shd_file.Nrr + ird * shd_file.Nrr + (i/2); + for (int i = 0; i < 2*shd_file.Nrr; i += 2 ) { + int press_index = itheta * shd_file.Nsd * shd_file.Nrx_per_range * shd_file.Nrr + isd * shd_file.Nrx_per_range * shd_file.Nrr + ird * shd_file.Nrr + (i/2); - double real_part = press[i]; - double imag_part = press[i+1]; + double real_part = press[i]; + double imag_part = press[i+1]; - if ( !::std::isnan(real_part) && !::std::isnan(imag_part) && !::std::isinf(real_part) && !::std::isinf(imag_part) ) { + if ( !::std::isnan(real_part) && !::std::isnan(imag_part) && !::std::isinf(real_part) && !::std::isinf(imag_part) ) { - shd_file.press_values[press_index] += ::std::complex(real_part, imag_part) ; + shd_file.press_values[press_index] += ::std::complex(real_part, imag_part) ; - if (woss_ptr->usingDebug()) ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() tx_depth = " << shd_file.tx_depths[isd] - << "; rx depth = " << shd_file.rx_depths[ird] << "; rx range = " << shd_file.rx_ranges[(i/2)] - << "; pressure = " << shd_file.press_values[press_index] << "; tx loss db = " - << Pressure::getTxLossDb( ::std::complex( real_part, imag_part ) ) << ::std::endl; + if (woss_ptr->usingDebug()) + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() tx_depth = " + << shd_file.tx_depths[isd] + << "; rx depth = " << shd_file.rx_depths[ird] << "; rx range = " << shd_file.rx_ranges[(i/2)] + << "; pressure = " << shd_file.press_values[press_index] << "; tx loss db = " + << Pressure::getTxLossDb( ::std::complex( real_part, imag_part ) ) << ::std::endl; + } + else { + shd_file.press_values[press_index] += ::std::complex( 0.0, 0.0 ) ; + } } - else { - shd_file.press_values[press_index] += ::std::complex( 0.0, 0.0 ) ; + } + } + } + + delete[] press; + press = NULL; + } + else if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_1) { + float* press = new float[2*shd_file_v1.Nrr]; + + for (int ifreq = 0; ifreq < shd_file_v1.Nfreq; ifreq++) { + + for (int itheta = 0; itheta < shd_file_v1.Ntheta; itheta++) { + + for (int isd = 0; isd < shd_file_v1.Nsd; isd++) { + + if (woss_ptr->usingDebug()) + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() Reading data: f = " + << ifreq << "; th = " << itheta << "; sd = " << isd << ::std::endl; + + for (int ird = 0; ird < shd_file_v1.Nrd; ird++) { + + int recnum = 10 + ifreq * shd_file_v1.Ntheta * shd_file_v1.Nsd * shd_file_v1.Nrx_per_range + + itheta * shd_file_v1.Nsd * shd_file_v1.Nrx_per_range + + isd * shd_file_v1.Nrx_per_range + + ird; + + file_reader.seekg( recnum * 4 * shd_file_v1.record_length, ::std::ios_base::beg ); //Move to end of previous record + if ( !file_reader.good()) { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::getShdFile() Seek to specified record failed in " + << file_name << ::std::endl; + exit(1); + } + file_reader.read(reinterpret_cast(press), 2*shd_file_v1.Nrr*sizeof(float)); + + for (int i = 0; i < 2*shd_file_v1.Nrr; i += 2 ) { + int press_index = ifreq * shd_file_v1.Ntheta * shd_file_v1.Nsd * shd_file_v1.Nrx_per_range * shd_file_v1.Nrr + + itheta * shd_file_v1.Nsd * shd_file_v1.Nrx_per_range * shd_file_v1.Nrr + + isd * shd_file_v1.Nrx_per_range * shd_file_v1.Nrr + ird * shd_file_v1.Nrr + + (i/2); + + double real_part = press[i]; + double imag_part = press[i+1]; + + if ( !::std::isnan(real_part) && !::std::isnan(imag_part) && !::std::isinf(real_part) && !::std::isinf(imag_part) ) { + shd_file_v1.press_values[press_index] += ::std::complex(real_part, imag_part) ; + + if (woss_ptr->usingDebug()) + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() + << ")::getShdFile() tx_depth = " << shd_file_v1.tx_depths[isd] + << "; rx depth = " << shd_file_v1.rx_depths[ird] << "; rx range = " << shd_file_v1.rx_ranges[(i/2)] + << "; pressure = " << shd_file_v1.press_values[press_index] << "; tx loss db = " + << Pressure::getTxLossDb( ::std::complex( real_part, imag_part ) ) << ::std::endl; + } + else { + shd_file_v1.press_values[press_index] += ::std::complex( 0.0, 0.0 ) ; + } + } } } } } + + delete[] press; + press = NULL; } + file_reader.close(); - delete[] press; - press = NULL; - shd_file_collected = true; return shd_file_collected; } -Pressure* ShdResReader::readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { +Pressure* ShdResReader::readAvgPressure(double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) { if (!shd_file_collected) return SDefHandler::instance()->getPressure()->create( Pressure::createNotValid() ); - return( SDefHandler::instance()->getPressure()->create( readMapAvgPressure( tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ) ) ); + return( SDefHandler::instance()->getPressure()->create( readMapAvgPressure(frequency, tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ) ) ); } -Pressure* ShdResReader::readPressure( double tx_depth, double rx_depth, double rx_range ) const { +Pressure* ShdResReader::readPressure(double frequency, double tx_depth, double rx_depth, double rx_range ) const { if (!shd_file_collected) return SDefHandler::instance()->getPressure()->create( Pressure::createNotValid() ); - return( SDefHandler::instance()->getPressure()->create( accessMap(tx_depth, rx_depth, rx_range) ) ); + return( SDefHandler::instance()->getPressure()->create( accessMap(frequency, tx_depth, rx_depth, rx_range) ) ); } -TimeArr* ShdResReader::readTimeArr( double tx_depth, double rx_depth, double rx_range ) const { +TimeArr* ShdResReader::readTimeArr(double frequency, double tx_depth, double rx_depth, double rx_range ) const { if (!shd_file_collected ) return SDefHandler::instance()->getTimeArr()->create( Pressure::createNotValid() ); - return( SDefHandler::instance()->getTimeArr()->create( accessMap( tx_depth, rx_depth, rx_range) ) ); + return( SDefHandler::instance()->getTimeArr()->create( accessMap(frequency, tx_depth, rx_depth, rx_range) ) ); } -::std::complex ShdResReader::readMapAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range, double theta ) { +::std::complex ShdResReader::accessMap(double frequency, double tx_depth, double rx_depth, double rx_range, double theta ) const { + const BellhopWoss* bwoss_ptr = dynamic_cast(woss_ptr); + assert( NULL != bwoss_ptr ); + + if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_0) { + return( shd_file.press_values[ shd_file.getPressureIndex( tx_depth, rx_depth, rx_range, theta ) ] ); + } + else if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_1) { + return( shd_file_v1.press_values[ shd_file_v1.getPressureIndex( frequency, tx_depth, rx_depth, rx_range, theta ) ] ); + } + else { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::accessMap() unkown Shd syntax " << ::std::endl; + exit(1); + } +} + + +::std::complex ShdResReader::readMapAvgPressure(double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range, double theta ) { if ( ( last_tx_depth == tx_depth ) && ( last_start_rx_depth == start_rx_depth ) && ( last_start_rx_range == start_rx_range ) && ( last_end_rx_depth == end_rx_depth ) && ( last_end_rx_range == end_rx_range ) ) return last_ret_value; else { + const BellhopWoss* bwoss_ptr = dynamic_cast(woss_ptr); + assert( NULL != bwoss_ptr ); + ::std::complex sum_press ( 0.0 , 0.0 ); double sum_cnt = 0; - int start_index = shd_file.getPressureIndex( tx_depth, start_rx_depth, start_rx_range, theta ); - int end_index = shd_file.getPressureIndex( tx_depth, end_rx_depth, end_rx_range, theta ); + int start_index; + int end_index; + + if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_0) { + start_index = shd_file.getPressureIndex( tx_depth, start_rx_depth, start_rx_range, theta ); + end_index = shd_file.getPressureIndex( tx_depth, end_rx_depth, end_rx_range, theta ); - for ( int i = start_index; i <= end_index; i++ ) { - sum_press += shd_file.press_values[i]; - sum_cnt++; + for ( int i = start_index; i <= end_index; i++ ) { + sum_press += shd_file.press_values[i]; + sum_cnt++; + } } - + else if (bwoss_ptr->getBellhopShdSyntax() == BELLHOP_CREATOR_SHD_FILE_SYNTAX_1) { + start_index = shd_file_v1.getPressureIndex( frequency, tx_depth, start_rx_depth, start_rx_range, theta ); + end_index = shd_file_v1.getPressureIndex( frequency, tx_depth, end_rx_depth, end_rx_range, theta ); + + for ( int i = start_index; i <= end_index; i++ ) { + sum_press += shd_file_v1.press_values[i]; + sum_cnt++; + } + } + else { + ::std::cout << "ShdResReader(" << woss_ptr->getWossId() << ")::accessMap() unkown Shd syntax " << ::std::endl; + exit(1); + } + last_tx_depth = tx_depth; last_start_rx_range = start_rx_range; last_end_rx_range = end_rx_range; diff --git a/woss/ac-toolbox-shd-reader.h b/woss/ac-toolbox-shd-reader.h index bb11ed2..e066c20 100644 --- a/woss/ac-toolbox-shd-reader.h +++ b/woss/ac-toolbox-shd-reader.h @@ -65,8 +65,8 @@ namespace woss { /** * Destructor */ - ~ShdData() { delete[] theta; delete[] tx_depths; delete[] rx_ranges; delete[] rx_depths; delete[] press_values ; } - + ~ShdData() { delete[] theta; delete[] tx_depths; delete[] rx_ranges; + delete[] rx_depths; delete[] press_values; } /** * Record byte length of a binary SHD file. See Bellhop code for more info @@ -85,7 +85,6 @@ namespace woss { */ float frequency; - /** * Total number of theta values. See Bellhop code for more info */ @@ -167,9 +166,139 @@ namespace woss { */ int getIndex( float value, float* array, int32_t array_size ) const; - }; + /** + * \brief class for storing data of any acoustic toolbox SHD file + * + * class ShdData stores Pressure provided by any acoustic toolbox SHD file + */ + class ShdData_v1 { + + public: + + ShdData_v1(); + + /** + * Destructor + */ + ~ShdData_v1() { delete[] frequencies; delete[] theta; delete[] tx_depths; delete[] rx_ranges; + delete[] rx_depths; delete[] press_values; } + + /** + * Record byte length of a binary SHD file. See Bellhop code for more info + */ + int32_t record_length; + + + /** + * Plot typename. See Bellhop code for more info + */ + char* plot_type; + + + /** + * Frequency value [Hz] + */ + double frequency; + + int32_t Nfreq; + + double* frequencies; + + /** + * Total number of theta values. See Bellhop code for more info + */ + int32_t Ntheta; + + /** + * Pointer to an array of theta values + */ + double* theta; + + + /** + * Total number of transmitter depths + */ + int32_t Nsd; + + /** + * Pointer to an array of transmitter depths [m] + */ + float* tx_depths; + + + /** + * Total number of receiver depths + */ + int32_t Nrd; + + /** + * Pointer to an array of receiver depths [m] + */ + float* rx_depths; + + + /** + * Total number of receiver ranges + */ + int32_t Nrr; + + /** + * Pointer to an array of receiver ranges [m] + */ + double* rx_ranges; + + /** + * Total number of receiver per range + */ + int32_t Nrx_per_range; + + double stabil_atten; + + /** + * Pointer to an array of complex\ values [m] + */ + ::std::complex* press_values; + + + /** + * Initializes the struct + */ + void initialize() { plot_type = NULL; frequency = 0.0; Nfreq = 0; frequencies = NULL; Ntheta = 0; + theta = NULL; Nrx_per_range = 0; record_length = 0; tx_depths = NULL; stabil_atten = 0.0; + rx_depths = NULL; rx_ranges = NULL; Nrr = 0; Nrd = 0; Nsd = 0; press_values = NULL; } + + + /** + * Returns the press_values index associated to given parameters + * @param tx_freq transmitter frequency [hZ] + * @param tx_depth transmitter depth [m] + * @param rx_depth receiver depth [m] + * @param rx_range receiver range [m] + * @param theta theta value + * @returns valid press_values index value + */ + int getPressureIndex( double tx_freq, double tx_depth, double rx_depth, double rx_range, double theta = 0.0 ) const; + + /** + * Returns the index of given array associated to given value + * @param value test value + * @param array valid pointer to an array + * @param array_size size of passed array + * @returns valid array index value + */ + int getIndex( float value, float* array, int32_t array_size ) const; + + /** + * Returns the index of given array associated to given value + * @param value test value + * @param array valid pointer to an array + * @param array_size size of passed array + * @returns valid array index value + */ + int getIndex( double value, double* array, int32_t array_size ) const; + }; /** * \brief Class for reading and manipulating results provided by any acoustic toolbox SHD file @@ -204,6 +333,7 @@ namespace woss { /** * Gets the average Pressure value in given rx range-depth box + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -211,27 +341,29 @@ namespace woss { * @param end_rx_range end receiver range [m] * @return a valid Pressure value; a not valid Pressure if shd_file hasn't been read yet **/ - virtual Pressure* readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); + virtual Pressure* readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ); /** * Gets a Pressure value of given range, depths + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid Pressure value; a not valid Pressure if shd_file hasn't been read yet **/ - virtual Pressure* readPressure( double tx_depth, double rx_depth, double rx_range ) const; + virtual Pressure* readPressure( double frequency, double tx_depth, double rx_depth, double rx_range ) const; /** * SHD files don't hold any time arrivals information. A special TimeArr is constructed from Pressure associated * to given paramaters. + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a special TimeArr that holds a single Pressure value and no delay information **/ - virtual TimeArr* readTimeArr( double tx_depth, double rx_depth, double rx_range ) const; + virtual TimeArr* readTimeArr( double frequency, double tx_depth, double rx_depth, double rx_range ) const; protected: @@ -259,6 +391,11 @@ namespace woss { */ ShdData shd_file; + /** + * Struct that holds Pressure data read from SHD file with V1 syntax + */ + ShdData_v1 shd_file_v1; + double last_tx_depth; double last_start_rx_depth; @@ -274,6 +411,7 @@ namespace woss { /** * Gets the average Pressure value in given rx range-depth box from ShdData Pressure array + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -282,18 +420,19 @@ namespace woss { * @param theta theta value * @return a valid Pressure value; a not valid Pressure if shd_file hasn't been read yet **/ - ::std::complex readMapAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range, double theta = 0.0 ); + ::std::complex readMapAvgPressure(double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range, double theta = 0.0 ); /** * Gets the Pressure value from ShdData Pressure array associated to given parameters + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth start receiver depth [m] * @param rx_range start receiver range [m] * @param theta theta value * @return a valid Pressure value; a not valid Pressure if shd_file hasn't been read yet **/ - ::std::complex accessMap( double tx_depth, double rx_depth, double rx_range, double theta = 0.0 ) const; + ::std::complex accessMap(double frequency, double tx_depth, double rx_depth, double rx_range, double theta = 0.0 ) const; /** @@ -311,15 +450,6 @@ namespace woss { }; - - //// - // inline functions - - inline ::std::complex ShdResReader::accessMap( double tx_depth, double rx_depth, double rx_range, double theta ) const { - return( shd_file.press_values[ shd_file.getPressureIndex( tx_depth, rx_depth, rx_range, theta ) ] ); - } - - } diff --git a/woss/bellhop-woss.cpp b/woss/bellhop-woss.cpp index b4752a6..0b50d0d 100644 --- a/woss/bellhop-woss.cpp +++ b/woss/bellhop-woss.cpp @@ -932,7 +932,7 @@ Pressure* BellhopWoss::getAvgPressure( double frequency, double tx_depth, double checkBoundaries( frequency, tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ); - Pressure* ret_val = res_reader_map.find(frequency)->second->readAvgPressure( tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ); + Pressure* ret_val = res_reader_map.find(frequency)->second->readAvgPressure(frequency, tx_depth, start_rx_depth, start_rx_range, end_rx_depth, end_rx_range ); *ret_val /= (double) total_runs; return ( ret_val ); } @@ -942,7 +942,7 @@ Pressure* BellhopWoss::getPressure( double frequency, double tx_depth, double rx assert( res_reader_map.size() > 0 ); checkBoundaries( frequency, tx_depth, rx_depth, rx_range, rx_depth, rx_range ); - Pressure* ret_val = res_reader_map.find(frequency)->second->readPressure( tx_depth, rx_depth, rx_range ); + Pressure* ret_val = res_reader_map.find(frequency)->second->readPressure(frequency, tx_depth, rx_depth, rx_range ); *ret_val /= (double) total_runs; return ( ret_val ); } @@ -952,7 +952,7 @@ TimeArr* BellhopWoss::getTimeArr( double frequency, double tx_depth, double rx_d assert( res_reader_map.size() > 0 ); checkBoundaries( frequency, tx_depth, rx_depth, rx_range, rx_depth, rx_range ); - TimeArr* ret_val = res_reader_map.find(frequency)->second->readTimeArr( tx_depth, rx_depth, rx_range ); + TimeArr* ret_val = res_reader_map.find(frequency)->second->readTimeArr( frequency, tx_depth, rx_depth, rx_range ); if ( debug ) ::std::cout << "BellhopWoss(" << woss_id << ")::getTimeArr() ret_val = " << *ret_val << ::std::endl; diff --git a/woss/res-reader.h b/woss/res-reader.h index bdd3459..3ad7f02 100644 --- a/woss/res-reader.h +++ b/woss/res-reader.h @@ -84,6 +84,7 @@ namespace woss { /** * Gets the average Pressure value in given rx range-depth box + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param start_rx_depth start receiver depth [m] * @param start_rx_range start receiver range [m] @@ -91,26 +92,28 @@ namespace woss { * @param end_rx_range end receiver range [m] * @return a valid Pressure value **/ - virtual Pressure* readAvgPressure( double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) = 0; + virtual Pressure* readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range ) = 0; /** * Gets a Pressure value for given range, depths + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid Pressure value **/ - virtual Pressure* readPressure( double tx_depth, double rx_depth, double rx_range ) const = 0; + virtual Pressure* readPressure( double frequency, double tx_depth, double rx_depth, double rx_range ) const = 0; /** * Gets a TimeArr value for given range, depths + * @param frequency frequency [hZ] * @param tx_depth transmitter depth [m] * @param rx_depth receiver depth [m] * @param rx_range receiver range [m] * @return a valid Pressure value **/ - virtual TimeArr* readTimeArr( double tx_depth, double rx_depth, double rx_range ) const = 0; + virtual TimeArr* readTimeArr(double frequency, double tx_depth, double rx_depth, double rx_range ) const = 0; /** diff --git a/woss/woss-manager-simple.h b/woss/woss-manager-simple.h index 52eca54..a57a0a4 100644 --- a/woss/woss-manager-simple.h +++ b/woss/woss-manager-simple.h @@ -74,6 +74,12 @@ namespace woss { virtual WossManagerSimple& eraseActiveWoss( const CoordZ& tx, const CoordZ& rx, double start_frequency, double end_frequency ); + /** + * Deletes all woss::Woss object + * @returns reference to *this + **/ + virtual WossManagerSimple& eraseAllWoss(); + /** * Deletes all created Woss instances * @return true if method was successful, false otherwise @@ -217,7 +223,23 @@ namespace woss { } } - + template< typename WMResDb > + WossManagerSimple< WMResDb >& WossManagerSimple< WMResDb >::eraseAllWoss() { + if (WMResDb::debug) ::std::cout << "WossManagerSimple::eraseAllWoss() map size = " << woss_map.size() << ::std::endl; + + for (WCIter it1 = woss_map.begin(); it1 != woss_map.end(); ++it1) { + for (WCZIter it2 = (it1->second).begin(); it2 != (it1->second).end(); ++it2) { + delete it2->second; + } + } + + woss_map.clear(); + + if (WMResDb::debug) ::std::cout << "WossManagerSimple::eraseAllWoss() final map size = " << woss_map.size() << ::std::endl; + + return *this; + } + template< typename WMResDb > WossManagerSimple< WMResDb >& WossManagerSimple< WMResDb >::eraseActiveWoss( const CoordZ& tx_coordz, const CoordZ& rx_coordz, double start_frequency, double end_frequency ) { if (WMResDb::debug) ::std::cout << "WossManagerSimple::eraseActiveWoss() tx coords " << tx_coordz << "; rx coords " diff --git a/woss/woss-manager.cpp b/woss/woss-manager.cpp index 6183f26..f29b935 100644 --- a/woss/woss-manager.cpp +++ b/woss/woss-manager.cpp @@ -451,7 +451,8 @@ void WossManagerResDbMT::checkConcurrentThreads() { else concurrent_threads = ::std::min( max_thread_number, concurrent_threads ); - ::std::cout << "WossManagerResDbMT::checkConcurrentThreads() " << concurrent_threads << ::std::endl; + if (debug) + ::std::cout << "WossManagerResDbMT::checkConcurrentThreads() " << concurrent_threads << ::std::endl; } diff --git a/woss/woss-manager.h b/woss/woss-manager.h index 2392ffb..30dc63b 100644 --- a/woss/woss-manager.h +++ b/woss/woss-manager.h @@ -124,7 +124,12 @@ namespace woss { **/ virtual WossManager& eraseActiveWoss( const CoordZ& tx, const CoordZ& rx, double start_frequency, double end_frequency ) = 0; - + /** + * Deletes all woss::Woss object + * @returns reference to *this + **/ + virtual WossManager& eraseAllWoss() = 0; + /** * Returns a valid Pressure* for given parameters * @param tx const reference to a valid CoordZ object ( transmitter ) diff --git a/woss/woss_db/res-pressure-bin-db-creator.cpp b/woss/woss_db/res-pressure-bin-db-creator.cpp index e8a4ba3..c7b497e 100644 --- a/woss/woss_db/res-pressure-bin-db-creator.cpp +++ b/woss/woss_db/res-pressure-bin-db-creator.cpp @@ -85,6 +85,8 @@ ResPressureBinDbCreator::~ResPressureBinDbCreator() { WossDb* const ResPressureBinDbCreator::createWossDb() { assert( pathname.length() > 0 ); + if ( debug ) ::std::cout << "ResPressureBinDbCreator::createWossDb() pathname = " << pathname << ::std::endl; + ResPressureTxtDb* woss_db = new ResPressureBinDb( pathname ); woss_db->setSpaceSampling(space_sampling); diff --git a/woss/woss_db/res-pressure-txt-db-creator.cpp b/woss/woss_db/res-pressure-txt-db-creator.cpp index 4569f36..abf896f 100644 --- a/woss/woss_db/res-pressure-txt-db-creator.cpp +++ b/woss/woss_db/res-pressure-txt-db-creator.cpp @@ -59,10 +59,13 @@ ResPressureTxtDbCreator::~ResPressureTxtDbCreator() { WossDb* const ResPressureTxtDbCreator::createWossDb() { assert( pathname.length() > 0 ); - + + if ( debug ) ::std::cout << "ResPressureTxtDbCreator::createWossDb() pathname = " << pathname << ::std::endl; + ResPressureTxtDb* woss_db = new ResPressureTxtDb( pathname ); - + woss_db->setSpaceSampling(space_sampling); + bool ok = initializeDb( woss_db ); assert( ok ); diff --git a/woss/woss_db/res-pressure-txt-db.cpp b/woss/woss_db/res-pressure-txt-db.cpp index f7976f7..7cd8486 100644 --- a/woss/woss_db/res-pressure-txt-db.cpp +++ b/woss/woss_db/res-pressure-txt-db.cpp @@ -314,7 +314,8 @@ void ResPressureTxtDb::printScreenMap() { bool ResPressureTxtDb::finalizeConnection() { - return importMap(); + importMap(); + return true; } diff --git a/woss/woss_db/woss-db-manager.cpp b/woss/woss_db/woss-db-manager.cpp index 97c6ff3..9b59c38 100644 --- a/woss/woss_db/woss-db-manager.cpp +++ b/woss/woss_db/woss-db-manager.cpp @@ -347,6 +347,78 @@ void WossDbManager::insertPressure( const CoordZ& tx_coord, const CoordZ& rx_coo } +bool WossDbManager::setCustomSSP(const ::std::string &sspString, const Coord& txCoord, double bearing, + double range, const Time& timeValue) +{ + SSP* ssp = SDefHandler::instance()->getSSP()->create(); + ::std::string sspTmp = sspString; + ::std::string::size_type tmp; + + int totalDepths = 0; + + tmp = sspTmp.find ("|"); + if (tmp == std::string::npos) { + ::std::cerr << "WossDbManager::setCustomSSP() separator | not found, string parsed = " << sspTmp << ::std::endl; + return false; + } + + std::string totDepths = sspTmp.substr (0, tmp); + sspTmp = sspTmp.substr (tmp + 1, sspTmp.npos); + totalDepths = ::std::atoi (totDepths.c_str ()); + + if(debug) { + ::std::cout << "WossDbManager::setCustomSSP() totalDepths = " << totalDepths << ::std::endl; + } + + if (totalDepths <= 0) { + ::std::cerr << "WossDbManager::setCustomSSP() totalDepths < 0 " << totalDepths << ::std::endl; + return false; + } + + for (int cnt = 0; cnt < totalDepths; ++cnt) { + double depth; + double sspValue; + + tmp = sspTmp.find ("|"); + if (tmp == std::string::npos) { + ::std::cerr << "WossDbManager::setCustomSSP() cnt = " << cnt + << "; separator | not found, string parsed = " << sspTmp << ::std::endl; + return false; + } + + std::string depthStr = sspTmp.substr (0, tmp); + sspTmp = sspTmp.substr (tmp + 1, sspTmp.npos); + depth = ::std::atof (depthStr.c_str ()); + + tmp = sspTmp.find ("|"); + if ((tmp == std::string::npos) && (cnt != totalDepths - 1)) { + ::std::cerr << "WossDbManager::setCustomSSP() cnt = " << cnt + << "; separator | not found, string parsed = " << sspTmp << ::std::endl; + return false; + } + + std::string sspValueStr = sspTmp.substr (0, tmp); + sspTmp = sspTmp.substr (tmp + 1, sspTmp.npos); + sspValue = ::std::atof (sspValueStr.c_str ()); + + if(debug) { + ::std::cout << "WossDbManager::setCustomSSP() cnt = " << cnt + << "; depth = " << depth << "; sspValue = " << sspValue << ::std::endl; + } + + if (sspValue < 0.0) { + ::std::cerr << "WossDbManager::setCustomSSP() cnt = " << cnt + << "; depth = " << depth << "< 0 " << ::std::endl; + return false; + } + else { + ssp->insertValue(depth, sspValue); + } + } + + return setCustomSSP(ssp, txCoord, bearing, range, timeValue); +} + bool WossDbManager::importCustomSSP( const ::std::string& filename, const Time& time, const Coord& tx_coord, double bearing ) { ::std::ifstream ssp_in ( filename.c_str() ); @@ -469,6 +541,83 @@ bool WossDbManager::importCustomSSP( const ::std::string& filename, const Time& return true; } +bool +WossDbManager::setCustomBathymetry(const ::std::string &bathyLine, const Coord& txCoord, double bearing) +{ + ::std::string bathyTmp = bathyLine; + ::std::string::size_type tmp; + + int totalRanges = 0; + + if (debug) { + ::std::cout << "WossDbManager::setCustomBathymetry() txCoord = " << txCoord + << "; bearing = " << bearing << ::std::endl; + } + + tmp = bathyTmp.find ("|"); + if (tmp == std::string::npos) { + ::std::cerr << "WossDbManager::setCustomBathymetry() " + << "separator | not found, string parsed = " << bathyTmp << ::std::endl; + return false; + } + + std::string totRanges = bathyTmp.substr (0, tmp); + bathyTmp = bathyTmp.substr (tmp + 1, bathyTmp.npos); + totalRanges = ::std::atoi (totRanges.c_str ()); + + if (debug) { + ::std::cout << "WossDbManager::setCustomBathymetry() " + << "totalRanges = " << totalRanges << ::std::endl; + } + + if (totalRanges <= 0) { + return false; + } + + for (int cnt = 0; cnt < totalRanges; ++cnt) { + double range; + double depth; + + tmp = bathyTmp.find ("|"); + if (tmp == std::string::npos) { + ::std::cerr << "WossDbManager::setCustomBathymetry() " + << "cnt = " << cnt + << "; separator | not found, string parsed:" << bathyTmp << ::std::endl; + + return false; + } + + std::string rangeStr = bathyTmp.substr (0, tmp); + bathyTmp = bathyTmp.substr (tmp + 1, bathyTmp.npos); + range = ::std::atof (rangeStr.c_str ()); + + tmp = bathyTmp.find ("|"); + if ((tmp == std::string::npos) && (cnt != totalRanges - 1)) { + ::std::cerr << "WossDbManager::setCustomBathymetry() " + << "cnt = " << cnt + << "; separator | not found, string parsed:" << bathyTmp << ::std::endl; + return false; + } + + std::string depthStr = bathyTmp.substr (0, tmp); + bathyTmp = bathyTmp.substr (tmp + 1, bathyTmp.npos); + depth = ::std::atof (depthStr.c_str ()); + + if (debug) { + ::std::cout << "WossDbManager::setCustomBathymetry() " + << " cnt = " << cnt << "; range = " << range + << "; depth = " << depth << ::std::endl; + } + + if (depth < 0.0) { + return false; + } + else { + setCustomBathymetry(&depth, txCoord, bearing, range); + } + } + return true; +} bool WossDbManager::importCustomBathymetry( const ::std::string& filename, const Coord& tx_coord, double bearing ) { ::std::ifstream bathy_in ( filename.c_str() ); @@ -492,5 +641,49 @@ bool WossDbManager::importCustomBathymetry( const ::std::string& filename, const return true; } +bool WossDbManager::setCustomSediment(const ::std::string &sedimentString, const Coord& txCoord, double bearing, double range) { - + ::std::string sedimentType; + ::std::string sedimTmp = sedimentString; + ::std::string::size_type tmp; + double param[5]; + + tmp = sedimTmp.find ("|"); + if (tmp == std::string::npos) { + ::std::cout << "WossDbManager::setCustomSediment() " + << "separator | not found, string parsed = " << sedimTmp << ::std::endl; + return false; + } + + sedimentType = sedimTmp.substr (0, tmp); + sedimTmp = sedimTmp.substr (tmp + 1, sedimTmp.npos); + + if (debug) { + ::std::cout << "WossDbManager::setCustomSediment() " + << "sedimentType = " << sedimentType << ::std::endl; + } + + for (int cnt = 0; cnt < 5; ++cnt) { + tmp = sedimTmp.find ("|"); + if ((tmp == std::string::npos) && (cnt != 5 - 1)) { + ::std::cerr << "WossDbManager::setCustomSediment() " + << "cnt = " << cnt << "; separator | not found, string parsed = " + << sedimTmp << ::std::endl; + + return false; + } + + std::string paramStr = sedimTmp.substr (0, tmp); + sedimTmp = sedimTmp.substr (tmp + 1, sedimTmp.npos); + param[cnt] = ::std::atof (paramStr.c_str ()); + + if (debug) { + ::std::cout << "WossDbManager::setCustomSediment() " + << "cnt = " << cnt << "; param = " << param[cnt] << ::std::endl; + } + } + + Sediment* sediment = SDefHandler::instance()->getSediment()->create(sedimentType, param[0], param[1], param[2], param[3], param[4]); + + return setCustomSediment(sediment, txCoord, bearing, range); +} diff --git a/woss/woss_db/woss-db-manager.h b/woss/woss_db/woss-db-manager.h index c4cf351..c99d1b5 100644 --- a/woss/woss_db/woss-db-manager.h +++ b/woss/woss_db/woss-db-manager.h @@ -369,7 +369,21 @@ namespace woss { bool setCustomSediment( Sediment* const sediment, const Coord& tx_coord = CCSediment::DB_CDATA_ALL_OUTER_KEYS, double bearing = CCSediment::DB_CDATA_ALL_MEDIUM_KEYS, double range = CCSediment::DB_CDATA_ALL_INNER_KEYS ); - + + /** + * Converts the input :std::string into a woss::Sediment object and binds it to the designed geometry. + * \param sediment_string SSP in string format. syntax: + * - Sed_typename|SSP[m/s]|vel_c[m/s]|vel_s[m/s]|dens[g/cm^3]|att_c[db/wavelength]|att_s[db/wavelength]|bottom_depth[m] + * \param txCoord the geometry originating geographical coordinates + * \param bearing the geometry bearing [radians] + * \param range the geometry range + * \returns true if successful, false otherwise + */ + bool setCustomSediment( const ::std::string &sediment_string, + const Coord& txCoord = CCSediment::DB_CDATA_ALL_OUTER_KEYS, + double bearing = CCSediment::DB_CDATA_ALL_MEDIUM_KEYS, + double range = CCSediment::DB_CDATA_ALL_INNER_KEYS ); + /** * Gets the custom Sediment for given generator Coord * @param tx_coord const reference to a valid Coord (generator coordinates) @@ -406,7 +420,23 @@ namespace woss { double bearing = CCSSP::DB_CDATA_ALL_MEDIUM_KEYS, double range = CCSSP::DB_CDATA_ALL_INNER_KEYS, const Time& time_value = CCSSP::DB_CDATA_ALL_TIME_KEYS ); - + + /** + * Converts the input ::std::string into a custom woss::SSP object and assign it to the designed geometry + * and simulation time validity. + * \param sspString SSP in string format. syntax: + * - tot_values|depth_1[m]|SSP[m/s]|....|depth_final[m]|SSP_final[m/s] + * \param txCoord the geometry originating geographical coordinates + * \param bearing the geometry bearing [radians] + * \param range the geometry range + * \param time_value the geometry time evolution step + * \returns true if successful, false otherwise + */ + bool setCustomSSP( const std::string& sspString, const Coord& txCoord = CCSSP::DB_CDATA_ALL_OUTER_KEYS, + double bearing = CCSSP::DB_CDATA_ALL_MEDIUM_KEYS, + double range = CCSSP::DB_CDATA_ALL_INNER_KEYS, + const Time& time_value = CCSSP::DB_CDATA_ALL_TIME_KEYS ); + /** * Imports a CustomSSP from file. \n * File format: @@ -468,7 +498,19 @@ namespace woss { bool setCustomBathymetry( Bathymetry* const bathymetry, const Coord& tx_coord = CCBathymetry::DB_CDATA_ALL_OUTER_KEYS, double bearing = CCBathymetry::DB_CDATA_ALL_MEDIUM_KEYS, double range = CCBathymetry::DB_CDATA_ALL_INNER_KEYS ); - + + /** + * Reads the input ::std::string and converts it into a custom woss::Bathymetry object and binds it to + * the input geometry + * \param bathyLine bathymetry in string format. syntax: + * - tot_ranges|range_1[m]|dept_1[n]|....|range_final[m]|depth_final[m] + * \param txCoord the geometry originating geographical coordinates + * \param bearing the geometry bearing [radians] + * \returns true if successful, false otherwise + */ + bool setCustomBathymetry (const ::std::string &bathyLine, const Coord& tx_coord = CCBathymetry::DB_CDATA_ALL_OUTER_KEYS, + double bearing = CCBathymetry::DB_CDATA_ALL_MEDIUM_KEYS); + /** * Imports a CustomBathymetry from file. The file has to be a two column format: Range [m] Depth [m] * @param filename const reference to a string @@ -616,7 +658,7 @@ namespace woss { } -inline WossDbManager& WossDbManager::eraseCustomSSP( const Coord& tx_coord, double bearing, double range, const Time& time_key ) { + inline WossDbManager& WossDbManager::eraseCustomSSP( const Coord& tx_coord, double bearing, double range, const Time& time_key ) { ccssp_map.erase( tx_coord, bearing, range, time_key ); return *this; } diff --git a/woss/woss_def/pressure-definitions.h b/woss/woss_def/pressure-definitions.h index b2c7b50..9569599 100644 --- a/woss/woss_def/pressure-definitions.h +++ b/woss/woss_def/pressure-definitions.h @@ -194,8 +194,17 @@ namespace woss { static double getTxLossDb( const ::std::complex& val ) { if ( val == ::std::complex( HUGE_VAL, HUGE_VAL ) ) return -HUGE_VAL; else if( val == ::std::complex( 0.0, 0.0 ) ) return HUGE_VAL; else return( -20.0 * log10( ::std::abs(val) ) ); } - - + + /** + * Returns the Transmission Loss measured in db + * @return the Transmission Loss [db] + **/ + double getTxLossDb() const { + if (isValid() == false) return -HUGE_VAL; + else if ( complex_pressure == ::std::complex( 0.0, 0.0 ) ) return HUGE_VAL; + else return ( -20.0 * log10( abs() )); + } + /** * Checks if the attuenuation provided by the complex pressure is truly an attenuation, * e.g. if abs < 1. If not, replace the pressure with the attenuation provided by Thorp absorption process at given frequency @@ -405,7 +414,7 @@ namespace woss { inline ::std::ostream& operator<<( ::std::ostream& os, const Pressure& instance ) { - os << instance.complex_pressure; + os << instance.complex_pressure << " TL = " << instance.getTxLossDb() << " dB"; return os; } diff --git a/woss/woss_def/random-generator-definitions.cpp b/woss/woss_def/random-generator-definitions.cpp index de6d465..b4c75e5 100644 --- a/woss/woss_def/random-generator-definitions.cpp +++ b/woss/woss_def/random-generator-definitions.cpp @@ -54,7 +54,7 @@ void RandomGenerator::initialize() { double RandomGenerator::getRand() const { if (!initialized) { - ::std::cerr << "RandomGenerator::getRand() WARNING this instance is not initialized!!" << ::std::endl; + ::std::cerr << "RandomGenerator::getRand() ERROR this instance is not initialized!!" << ::std::endl; exit(1); } @@ -64,7 +64,7 @@ double RandomGenerator::getRand() const { int RandomGenerator::getRandInt() const { if (!initialized) { - ::std::cerr << "RandomGenerator::getRandInt() WARNING this instance is not initialized!!" << ::std::endl; + ::std::cerr << "RandomGenerator::getRandInt() ERROR this instance is not initialized!!" << ::std::endl; exit(1); }