From 35d12ce2c68b716f01982162097d5f6163ff7e1b Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Tue, 28 May 2024 15:40:16 +0200 Subject: [PATCH 001/179] pronti per inserire le anomalie --- weatherGenerator/weatherGenerator.cpp | 17 +++++++++-------- weatherGenerator/weatherGenerator.h | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 320b0f40..bcffb85e 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -993,12 +993,12 @@ bool computeClimate(TweatherGenClimate &wgClimate, int firstYear, int nrRepetiti return true; } -bool makeScenario(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, +bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly *XMLAnomaly, TweatherGenClimate& wGenClimate, - int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, + int nrRepetitions, int myPredictionYear, int *wgDoy1, int *wgDoy2, float rainfallThreshold) { - /*TweatherGenClimate wGen; + TweatherGenClimate wGen; std::vector dailyPredictions; Crit3DDate myFirstDatePrediction, seasonFirstDate, seasonLastDate; @@ -1010,7 +1010,7 @@ bool makeScenario(QString outputFileName, char separator, XMLSeasonalAnomaly* XM unsigned int obsIndex; unsigned int addday = 0; bool isLastMember = false; - + /* // it checks if observed data includes the last 9 months before wgDoy1 int nrDaysBeforeWgDoy1; if (! checkLastYearDate(lastYearDailyObsData->inputFirstDate, lastYearDailyObsData->inputLastDate, @@ -1025,11 +1025,11 @@ bool makeScenario(QString outputFileName, char separator, XMLSeasonalAnomaly* XM { nrMembers += XMLAnomaly->modelMember[i].toUInt(); } - - nrYears = nrMembers * unsigned(nrRepetitions); - + */ + //nrYears = nrMembers * unsigned(nrRepetitions); + nrYears = nrRepetitions; firstYear = myPredictionYear; - + /* // wgDoy1 within myPredictionYear, wgDoy2 within myPredictionYear+1 if (wgDoy1 < wgDoy2) lastYear = firstYear + signed(nrYears) - 1; @@ -1149,3 +1149,4 @@ bool makeScenario(QString outputFileName, char separator, XMLSeasonalAnomaly* XM */ return true; } + diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index 6fa5e412..20e0d95e 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -123,9 +123,9 @@ void clearInputData(TinputObsData &myData); - bool makeScenario(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, + bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly* XMLAnomaly, TweatherGenClimate& wGenClimate, - int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, + int nrRepetitions, int myPredictionYear, int* wgDoy1, int* wgDoy2, float rainfallThreshold); From 4c0b2a4799702ff5f458bff019473690b5137735 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Tue, 28 May 2024 17:59:47 +0200 Subject: [PATCH 002/179] loadCsvDepthsSingleWell --- waterTable/importData.cpp | 63 +++++++++++++++++++++++++++++++++++++++ waterTable/importData.h | 1 + 2 files changed, 64 insertions(+) diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index a70eb0cf..747c21a4 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -168,3 +168,66 @@ bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTabl return true; } +bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) +{ + QFile myFile(csvDepths); + QList errorList; + + int posDate = 0; + int posDepth = 1; + + int nFields = 2; + bool ok; + errorStr = ""; + + if (! myFile.open(QFile::ReadOnly | QFile::Text) ) + { + errorStr = "csvFileName file does not exist"; + return false; + } + else + { + QTextStream in(&myFile); + //skip header + QString line = in.readLine(); + while (!in.atEnd()) + { + line = in.readLine(); + QList items = line.split(","); + items.removeAll({}); + if (items.size() < nFields) + { + errorList.append(line); + wrongLines++; + continue; + } + items[posDate] = items[posDate].simplified(); + QDate date = QDate::fromString(items[posDate].remove(QChar('"')),"yyyy-MM-dd"); + if (! date.isValid()) + { + errorList.append(line); + wrongLines++; + continue; + } + items[posDepth] = items[posDepth].simplified(); + int value = items[posDepth].remove(QChar('"')).toInt(&ok); + if (!ok || value == NODATA || value < 0 || value > waterTableMaximumDepth) + { + errorList.append(line); + wrongLines++; + continue; + } + + well.insertData(date, value); + } + } + myFile.close(); + + if (wrongLines > 0) + { + errorStr = "ID not existing or with invalid data or value:\n" + errorList.join("\n"); + } + + return true; +} + diff --git a/waterTable/importData.h b/waterTable/importData.h index e42b085d..1b5a433d 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -8,6 +8,7 @@ bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString &errorStr, int &wrongLines); bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); +bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H From 16141320042f38e18e3b65d299f32475601e7306 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 28 May 2024 18:09:09 +0200 Subject: [PATCH 003/179] fix show grid --- graphics/mapGraphicsRasterObject.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/graphics/mapGraphicsRasterObject.cpp b/graphics/mapGraphicsRasterObject.cpp index 051aab8f..1ca41644 100644 --- a/graphics/mapGraphicsRasterObject.cpp +++ b/graphics/mapGraphicsRasterObject.cpp @@ -240,6 +240,7 @@ bool RasterObject::initializeUTM(gis::Crit3DRasterGrid* myRaster, const gis::Cri setDrawing(true); setDrawBorders(isGrid); + setVisible(true); isLoaded = true; return true; @@ -271,7 +272,8 @@ bool RasterObject::initializeLatLon(gis::Crit3DRasterGrid* myRaster, const gis:: } setDrawing(true); - setDrawBorders(isGrid_); + setDrawBorders(isGrid); + setVisible(true); isLoaded = true; return true; From d46edacd31e0157a8881d23d64f288d4ad844869 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 29 May 2024 10:17:36 +0200 Subject: [PATCH 004/179] remove unused include --- waterTable/well.h | 1 - 1 file changed, 1 deletion(-) diff --git a/waterTable/well.h b/waterTable/well.h index fd05e4e0..95db5eec 100644 --- a/waterTable/well.h +++ b/waterTable/well.h @@ -5,7 +5,6 @@ #include #include #include -#include "meteoPoint.h" class Well { From cc97d67a663736a8282faa61204d5b580a45f764 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 29 May 2024 11:04:21 +0200 Subject: [PATCH 005/179] call loadCsvDepthsSingleWell --- waterTable/importData.cpp | 6 +++--- waterTable/importData.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index 747c21a4..f236cb2d 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -168,7 +168,7 @@ bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTabl return true; } -bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) +bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines) { QFile myFile(csvDepths); QList errorList; @@ -203,7 +203,7 @@ bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximum } items[posDate] = items[posDate].simplified(); QDate date = QDate::fromString(items[posDate].remove(QChar('"')),"yyyy-MM-dd"); - if (! date.isValid()) + if (! date.isValid() || date < climateObsFirstDate || date > climateObsLastDate) { errorList.append(line); wrongLines++; @@ -225,7 +225,7 @@ bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximum if (wrongLines > 0) { - errorStr = "ID not existing or with invalid data or value:\n" + errorList.join("\n"); + errorStr = "Invalid data or value or data out of range:\n" + errorList.join("\n"); } return true; diff --git a/waterTable/importData.h b/waterTable/importData.h index 1b5a433d..5aa1c55c 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -8,7 +8,7 @@ bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString &errorStr, int &wrongLines); bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); -bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); +bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H From 620b7ecfa816d8e94d8b383dfea70570ffa4cc78 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 29 May 2024 11:16:00 +0200 Subject: [PATCH 006/179] fix call loadCsvDepthsSingleWell --- waterTable/importData.cpp | 4 ++-- waterTable/importData.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index f236cb2d..a2606425 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -168,7 +168,7 @@ bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTabl return true; } -bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines) +bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines) { QFile myFile(csvDepths); QList errorList; @@ -218,7 +218,7 @@ bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximum continue; } - well.insertData(date, value); + well->insertData(date, value); } } myFile.close(); diff --git a/waterTable/importData.h b/waterTable/importData.h index 5aa1c55c..bed234a5 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -8,7 +8,7 @@ bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString &errorStr, int &wrongLines); bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); -bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines); +bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H From 03e39a2f80e12dbc8867c0b0fc446cf06a25a455 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 29 May 2024 11:44:21 +0200 Subject: [PATCH 007/179] check number of values --- waterTable/well.cpp | 22 ++++++++++++++++++++++ waterTable/well.h | 1 + 2 files changed, 23 insertions(+) diff --git a/waterTable/well.cpp b/waterTable/well.cpp index 908506fe..b06cba42 100644 --- a/waterTable/well.cpp +++ b/waterTable/well.cpp @@ -1,4 +1,5 @@ #include "well.h" +#include Well::Well() { @@ -77,3 +78,24 @@ QDate Well::getLastDate() } return lastDate; } + +int Well::minValuesPerMonth() +{ + QMapIterator it(depths); + std::vector H_num; + for (int myMonthIndex = 0; myMonthIndex < 12; myMonthIndex++) + { + H_num.push_back(0); + } + while (it.hasNext()) + { + it.next(); + QDate myDate = it.key(); + int myMonth = myDate.month(); + int myMonthIndex = myMonth - 1; + H_num[myMonthIndex] = H_num[myMonthIndex] + 1; + } + + auto min = min_element(H_num.begin(), H_num.end()); + return *min; +} diff --git a/waterTable/well.h b/waterTable/well.h index 95db5eec..36a5ee04 100644 --- a/waterTable/well.h +++ b/waterTable/well.h @@ -27,6 +27,7 @@ class Well int getObsDepthNr(); QMap getObsDepths() const; + int minValuesPerMonth(); private: QString id; From ee809c9e6a56aee36f582be58bbd689649aab4f1 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 29 May 2024 12:18:47 +0200 Subject: [PATCH 008/179] pass vector instead meteoPoint to waterTable --- project/project.cpp | 20 +++++++++++++++++++- waterTable/waterTable.cpp | 34 +++++++++++++++++++++++++--------- waterTable/waterTable.h | 7 +++++-- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 8064874e..2f123036 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4633,7 +4633,25 @@ bool Project::computeSingleWell(int indexWell) return false; } int maxNrDays = 730; // attualmente fisso - WaterTable waterTable(&linkedMeteoPoint, *meteoSettings, gisSettings); + + std::vector inputTMin; + std::vector inputTMax; + std::vector inputPrec; + + for (int i = 0; i < linkedMeteoPoint.nrObsDataDaysD; i++) + { + Crit3DDate myDate = linkedMeteoPoint.getFirstDailyData().addDays(i); + float Tmin = linkedMeteoPoint.getMeteoPointValueD(myDate, dailyAirTemperatureMin); + float Tmax = linkedMeteoPoint.getMeteoPointValueD(myDate, dailyAirTemperatureMax); + float prec = linkedMeteoPoint.getMeteoPointValueD(myDate, dailyPrecipitation); + inputTMin.push_back(Tmin); + inputTMax.push_back(Tmax); + inputPrec.push_back(prec); + } + QDate firstDate(linkedMeteoPoint.getFirstDailyData().year, linkedMeteoPoint.getFirstDailyData().month, linkedMeteoPoint.getFirstDailyData().day); + QDate lastDate(linkedMeteoPoint.getLastDailyData().year, linkedMeteoPoint.getLastDailyData().month, linkedMeteoPoint.getLastDailyData().day); + + WaterTable waterTable(inputTMin, inputTMax, inputPrec, firstDate, lastDate, *meteoSettings, gisSettings); waterTable.computeWaterTable(wellPoints[indexWell], maxNrDays); waterTable.viewWaterTableSeries(); // prepare series to show waterTableList.push_back(waterTable); diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 9fc3730e..0b339ba5 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -2,11 +2,10 @@ #include "commonConstants.h" #include "weatherGenerator.h" -WaterTable::WaterTable(Crit3DMeteoPoint *linkedMeteoPoint, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings) - : linkedMeteoPoint(linkedMeteoPoint), meteoSettings(meteoSettings), gisSettings(gisSettings) +WaterTable::WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, + Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings) + : inputTMin(inputTMin), inputTMax(inputTMax), inputPrec(inputPrec), firstMeteoDate(firstMeteoDate), lastMeteoDate(lastMeteoDate), meteoSettings(meteoSettings), gisSettings(gisSettings) { - firstMeteoDate = QDate(linkedMeteoPoint->getFirstDailyData().year, linkedMeteoPoint->getFirstDailyData().month, linkedMeteoPoint->getFirstDailyData().day); - lastMeteoDate = QDate(linkedMeteoPoint->getLastDailyData().year, linkedMeteoPoint->getLastDailyData().month, linkedMeteoPoint->getLastDailyData().day); } QString WaterTable::getIdWell() const @@ -195,13 +194,29 @@ bool WaterTable::computeETP_allSeries() float sumCWB = 0; int nrValidDays = 0; + int index = 0; + float Tmin = NODATA; + float Tmax = NODATA; + float prec = NODATA; + float etp = NODATA; for (QDate myDate = firstMeteoDate; myDate<=lastMeteoDate; myDate=myDate.addDays(1)) { Crit3DDate date(myDate.day(), myDate.month(), myDate.year()); - float Tmin = linkedMeteoPoint->getMeteoPointValueD(date, dailyAirTemperatureMin); - float Tmax = linkedMeteoPoint->getMeteoPointValueD(date, dailyAirTemperatureMax); - float prec = linkedMeteoPoint->getMeteoPointValueD(date, dailyPrecipitation); - float etp = dailyEtpHargreaves(Tmin, Tmax, date, myLat,&meteoSettings); + if (index > inputTMin.size() || index > inputTMax.size() || index > inputPrec.size()) + { + etp = NODATA; + if (index < inputPrec.size()) + { + prec = inputPrec[index]; + } + } + else + { + Tmin = inputTMin[index]; + Tmax = inputTMax[index]; + prec = inputPrec[index]; + etp = dailyEtpHargreaves(Tmin, Tmax, date, myLat,&meteoSettings); + } etpValues.push_back(etp); precValues.push_back(prec); if (etp != NODATA && prec != NODATA) @@ -209,6 +224,7 @@ bool WaterTable::computeETP_allSeries() sumCWB = sumCWB + (prec - etp); nrValidDays = nrValidDays + 1; } + index = index + 1; } if (nrValidDays > 0) @@ -217,7 +233,7 @@ bool WaterTable::computeETP_allSeries() } else { - error = "Missing data: " + QString::fromStdString(linkedMeteoPoint->name); + error = "Missing data"; return false; } diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 1c64e31d..13fccc78 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -12,7 +12,8 @@ class WaterTable { public: - WaterTable(Crit3DMeteoPoint* linkedMeteoPoint, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings); + WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, + Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings); QString getIdWell() const; QDate getFirstDateWell(); QDate getLastDateWell(); @@ -45,7 +46,6 @@ class WaterTable QMap getObsDepths(); private: - Crit3DMeteoPoint* linkedMeteoPoint; Crit3DMeteoSettings meteoSettings; gis::Crit3DGisSettings gisSettings; QDate firstDateWell; @@ -55,6 +55,9 @@ class WaterTable Well well; QString error; + std::vector inputTMin; + std::vector inputTMax; + std::vector inputPrec; std::vector etpValues; std::vector precValues; From 61cc169d44ca8132e09732317add45283bed2808 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 29 May 2024 12:50:43 +0200 Subject: [PATCH 009/179] change include --- waterTable/waterTable.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 13fccc78..ab27ed1d 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -1,12 +1,18 @@ #ifndef WATERTABLE_H #define WATERTABLE_H -#include "well.h" -#include "meteoPoint.h" -#include "meteoGrid.h" +#ifndef WELL_H + #include "well.h" +#endif +#ifndef METEO_H + #include "meteo.h" +#endif +#ifndef GIS_H + #include "gis.h" +#endif #include -#define MAXWELLDISTANCE 5000 // distanza max: 10 km +#define MAXWELLDISTANCE 5000 // distanza max: 5 km #define WATERTABLE_MAXDELTADAYS 90 class WaterTable From d80f64c9865839055061b11b650aca95dc2b893a Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Wed, 29 May 2024 15:28:43 +0200 Subject: [PATCH 010/179] update scenario aggiunta anomalie --- weatherGenerator/weatherGenerator.cpp | 73 +++++++++++++++++++++++++++ weatherGenerator/weatherGenerator.h | 2 + 2 files changed, 75 insertions(+) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index bcffb85e..61cb095d 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -662,6 +662,79 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, return true; } +bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, int anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) +{ + unsigned int i = 0; + QString myVar; + float myValue = 0.0; + + bool result; + + // loop for all XMLValuesList (Tmin, Tmax, TminVar, TmaxVar, Prec3M, Wetdays) + for (i = 0; i < 4; i++) + { + /*if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") + { + myVar = XMLAnomaly->forecast[i].type.toUpper(); + result = false; + + if (XMLAnomaly->forecast[i].value[modelIndex] != nullptr) + myValue = XMLAnomaly->forecast[i].value[modelIndex].toFloat(); + else + myValue = NODATA; + + if (int(myValue) != int(NODATA)) + { + if ( (myVar == "TMIN") || (myVar == "AVGTMIN") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmin, wGen.monthly.monthlyTmin); + else if ( (myVar == "TMAX") || (myVar == "AVGTMAX") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmax, wGen.monthly.monthlyTmax); + else if ( (myVar == "PREC3M") || (myVar == "PREC") ) + result = assignAnomalyPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.sumPrec, wGen.monthly.sumPrec); + else if ( (myVar == "WETDAYSFREQUENCY") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.fractionWetDays, wGen.monthly.fractionWetDays); + else if ( (myVar == "WETWETDAYSFREQUENCY") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.probabilityWetWet, wGen.monthly.probabilityWetWet); + else if ( (myVar == "DELTATMAXDRYWET") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.dw_Tmax, wGen.monthly.dw_Tmax); + } + else + { + // not critical variables + if ((myVar == "DELTATMAXDRYWET") || (myVar == "WETWETDAYSFREQUENCY")) + result = true; + } + + if (result == false) + { + qDebug() << "wrong anomaly: " + myVar; + return false; + } + }*/ + } + + /* DEBUG + QString anomaly="anomaly.txt"; + QFile file(anomaly); + file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text); + QTextStream stream( &file ); + for (int m = 0; m < 12; m++) + { + stream << "month = " << m +1 << endl; + stream << "wGen.monthly.monthlyTmin = " << wGen.monthly.monthlyTmin[m] << endl; + stream << "wGen.monthly.monthlyTmax = " << wGen.monthly.monthlyTmax[m] << endl; + stream << "wGen.monthly.sumPrec = " << wGen.monthly.sumPrec[m] << endl; + stream << "wGen.monthly.stDevTmin[m] = " << wGen.monthly.stDevTmin[m] << endl; + stream << "wGen.monthly.stDevTmax = " << wGen.monthly.stDevTmax[m] << endl; + stream << "wGen.monthly.fractionWetDays[m] = " << wGen.monthly.fractionWetDays[m] << endl; + stream << "wGen.monthly.probabilityWetWet[m] = " << wGen.monthly.probabilityWetWet[m] << endl; + stream << "wGen.monthly.dw_Tmax[m] = " << wGen.monthly.dw_Tmax[m] << endl; + stream << "-------------------------------------------" << endl; + } + */ + + return true; +} /*! * \name makeSeasonalForecast diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index 20e0d95e..58f24fa0 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -108,6 +108,8 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, float* myWGMonthlyVarNoAnomaly, float* myWGMonthlyVar); + bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, int anomalyMonth2, + TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen); bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, TweatherGenClimate& wGenClimate, TinputObsData* lastYearDailyObsData, From bd14e46a860c2a2b3e75b4fa561b588263dae4f7 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 29 May 2024 16:06:12 +0200 Subject: [PATCH 011/179] update square object --- dbMeteoPoints/dbMeteoPointsHandler.cpp | 6 ++--- graphics/squareMarker.cpp | 37 +++++--------------------- graphics/squareMarker.h | 19 +++++++------ project/project.cpp | 19 +++++++++---- waterTable/waterTableChartView.cpp | 4 +-- 5 files changed, 34 insertions(+), 51 deletions(-) diff --git a/dbMeteoPoints/dbMeteoPointsHandler.cpp b/dbMeteoPoints/dbMeteoPointsHandler.cpp index 5f02bc48..61fb2d82 100644 --- a/dbMeteoPoints/dbMeteoPointsHandler.cpp +++ b/dbMeteoPoints/dbMeteoPointsHandler.cpp @@ -242,7 +242,7 @@ QDateTime Crit3DMeteoPointsDbHandler::getLastDate(frequencyType frequency) qry.prepare( "SELECT name FROM sqlite_master WHERE type='table' AND name like :dayHour ESCAPE '^'"); qry.bindValue(":dayHour", "%^_" + dayHour + "%"); - if( !qry.exec() ) + if(! qry.exec() ) { errorStr = qry.lastError().text(); } @@ -274,11 +274,11 @@ QDateTime Crit3DMeteoPointsDbHandler::getLastDate(frequencyType frequency) if (qry.next()) { dateStr = qry.value(0).toString(); - if (!dateStr.isEmpty()) + if (! dateStr.isEmpty()) { if (frequency == daily) { - currentLastDate = QDateTime::fromString(dateStr,"yyyy-MM-dd"); + currentLastDate = QDateTime::fromString(dateStr, "yyyy-MM-dd"); } else if (frequency == hourly) { diff --git a/graphics/squareMarker.cpp b/graphics/squareMarker.cpp index 8545c5ea..558fb63c 100644 --- a/graphics/squareMarker.cpp +++ b/graphics/squareMarker.cpp @@ -2,42 +2,17 @@ #include "squareMarker.h" -SquareMarker::SquareMarker(qreal side,bool sizeIsZoomInvariant, QColor fillColor, MapGraphicsObject *parent) : +SquareMarker::SquareMarker(qreal side, bool sizeIsZoomInvariant, QColor fillColor, MapGraphicsObject *parent) : SquareObject(side, sizeIsZoomInvariant, fillColor, parent) { - this->setFlag(MapGraphicsObject::ObjectIsSelectable, false); - this->setFlag(MapGraphicsObject::ObjectIsMovable, false); - this->setFlag(MapGraphicsObject::ObjectIsFocusable, false); + setFlag(MapGraphicsObject::ObjectIsSelectable, false); + setFlag(MapGraphicsObject::ObjectIsMovable, false); + setFlag(MapGraphicsObject::ObjectIsFocusable, false); _id = ""; - _currentValue = NODATA; _active = true; } -void SquareMarker::setId(std::string id) -{ - _id = id; -} - -std::string SquareMarker::id() const -{ - return _id; -} - -void SquareMarker::setCurrentValue(float currentValue) -{ - _currentValue = currentValue; -} - -bool SquareMarker::active() const -{ - return _active; -} - -void SquareMarker::setActive(bool active) -{ - _active = active; -} void SquareMarker::setToolTip() { @@ -46,9 +21,9 @@ void SquareMarker::setToolTip() QString toolTipText = QString("Point: %1
") .arg(idpoint); - if (_currentValue != NODATA) + if (currentValue() != NODATA) { - QString value = QString::number(_currentValue); + QString value = QString::number(currentValue()); toolTipText += QString("value: %1 ").arg(value); } diff --git a/graphics/squareMarker.h b/graphics/squareMarker.h index 19d6959e..dff81cc5 100644 --- a/graphics/squareMarker.h +++ b/graphics/squareMarker.h @@ -8,21 +8,20 @@ { Q_OBJECT + private: + std::string _id; + bool _active; + public: explicit SquareMarker(qreal side, bool sizeIsZoomInvariant, QColor fillColor, MapGraphicsObject *parent = nullptr); - std::string id() const; - bool active() const; + std::string id() const { return _id; } + void setId(std::string id) { _id = id; } - void setId(std::string id); - void setActive(bool active); - void setCurrentValue(float currentValue); - void setToolTip(); + bool active() const { return _active; } + void setActive(bool active) { _active = active; } - private: - std::string _id; - bool _active; - float _currentValue; + void setToolTip(); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/project/project.cpp b/project/project.cpp index 8064874e..a543569a 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -1048,7 +1048,7 @@ bool Project::loadMeteoPointsDB(QString fileName) closeMeteoPointsDB(); - logInfoGUI("Load meteo points DB = " + fileName); + logInfoGUI("Load meteo points DB: " + fileName); dbPointsFileName = fileName; QString dbName = getCompleteFileName(fileName, PATH_METEOPOINT); @@ -1077,7 +1077,7 @@ bool Project::loadMeteoPointsDB(QString fileName) errorString = ""; if (! meteoPointsDbHandler->getPropertiesFromDb(listMeteoPoints, gisSettings, errorString)) { - errorString = "Error in reading table 'point_properties'\n" + errorString; + errorString = "Error in reading the table point_properties\n" + errorString; closeMeteoPointsDB(); return false; } @@ -1085,7 +1085,7 @@ bool Project::loadMeteoPointsDB(QString fileName) nrMeteoPoints = listMeteoPoints.size(); if (nrMeteoPoints == 0) { - errorString = "Missing data in the table 'point_properties'\n" + errorString; + errorString = "Missing data in the table point_properties\n" + errorString; closeMeteoPointsDB(); return false; } @@ -1669,6 +1669,7 @@ bool Project::loadMeteoGridMonthlyData(QDate firstDate, QDate lastDate, bool sho return true; } + QDateTime Project::findDbPointLastTime() { QDateTime lastTime; @@ -1677,7 +1678,10 @@ QDateTime Project::findDbPointLastTime() QDateTime lastDateD; lastDateD.setTimeSpec(Qt::UTC); lastDateD = meteoPointsDbHandler->getLastDate(daily); - if (! lastDateD.isNull()) lastTime = lastDateD; + if (! lastDateD.isNull()) + { + lastTime = lastDateD; + } QDateTime lastDateH; lastDateH.setTimeSpec(Qt::UTC); @@ -1685,15 +1689,20 @@ QDateTime Project::findDbPointLastTime() if (! lastDateH.isNull()) { - if (! lastTime.isNull()) + if (! lastDateD.isNull()) + { lastTime = (lastDateD > lastDateH) ? lastDateD : lastDateH; + } else + { lastTime = lastDateH; + } } return lastTime; } + QDateTime Project::findDbPointFirstTime() { QDateTime firstTime; diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index 83719422..5d5b4faf 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -31,10 +31,10 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : m_tooltip->hide(); } + void WaterTableChartView::draw(std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths) { - - int nDays = myDates.size(); + int nDays = int(myDates.size()); QDateTime myDateTime; myDateTime.setTime(QTime(0,0,0)); for (int day = 0; day < nDays; day++) From 9190e172d48cb4b129fa937b76bbfb74ed329143 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 29 May 2024 17:54:37 +0200 Subject: [PATCH 012/179] fix loadDBMeteo --- dbMeteoPoints/dbMeteoPointsHandler.cpp | 4 +- graphics/squareMarker.cpp | 5 +- graphics/squareMarker.h | 4 -- project/project.cpp | 79 ++++++++++++-------------- project/project.h | 2 +- waterTable/importData.cpp | 64 ++++++++++++++++----- waterTable/importData.h | 4 +- 7 files changed, 92 insertions(+), 70 deletions(-) diff --git a/dbMeteoPoints/dbMeteoPointsHandler.cpp b/dbMeteoPoints/dbMeteoPointsHandler.cpp index 61fb2d82..851af863 100644 --- a/dbMeteoPoints/dbMeteoPointsHandler.cpp +++ b/dbMeteoPoints/dbMeteoPointsHandler.cpp @@ -278,7 +278,9 @@ QDateTime Crit3DMeteoPointsDbHandler::getLastDate(frequencyType frequency) { if (frequency == daily) { - currentLastDate = QDateTime::fromString(dateStr, "yyyy-MM-dd"); + myDate = QDate::fromString(dateStr, "yyyy-MM-dd"); + myTime = QTime(12, 0, 0, 0); + currentLastDate = QDateTime(myDate, myTime, Qt::UTC); } else if (frequency == hourly) { diff --git a/graphics/squareMarker.cpp b/graphics/squareMarker.cpp index 558fb63c..a2581512 100644 --- a/graphics/squareMarker.cpp +++ b/graphics/squareMarker.cpp @@ -9,17 +9,14 @@ SquareMarker::SquareMarker(qreal side, bool sizeIsZoomInvariant, QColor fillColo setFlag(MapGraphicsObject::ObjectIsMovable, false); setFlag(MapGraphicsObject::ObjectIsFocusable, false); - _id = ""; _active = true; } void SquareMarker::setToolTip() { - QString idpoint = QString::fromStdString(_id); - QString toolTipText = QString("Point: %1
") - .arg(idpoint); + .arg(id()); if (currentValue() != NODATA) { diff --git a/graphics/squareMarker.h b/graphics/squareMarker.h index dff81cc5..ca884df2 100644 --- a/graphics/squareMarker.h +++ b/graphics/squareMarker.h @@ -9,15 +9,11 @@ Q_OBJECT private: - std::string _id; bool _active; public: explicit SquareMarker(qreal side, bool sizeIsZoomInvariant, QColor fillColor, MapGraphicsObject *parent = nullptr); - std::string id() const { return _id; } - void setId(std::string id) { _id = id; } - bool active() const { return _active; } void setActive(bool active) { _active = active; } diff --git a/project/project.cpp b/project/project.cpp index a543569a..8f8727d7 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4492,71 +4492,64 @@ void Project::closeProgressBar() } } -bool Project::findTempMinMax(meteoVariable myVar) -{ - float min; - float max; - float value; - int i = 0; +bool Project::findTemperatureRange(meteoVariable myVar) +{ if (nrMeteoPoints == 0) return false; + // check frequency and variable frequencyType myFreq = getVarFrequency(myVar); - Crit3DDate myDate = getCrit3DDate(this->getCurrentDate()); - int myHour = this->getCurrentHour(); - if (myFreq == daily) { if (myVar != dailyAirTemperatureAvg && myVar != dailyAirTemperatureMax && myVar != dailyAirTemperatureMin) return false; - - do { - min = meteoPoints[i].getMeteoPointValueD(myDate, myVar); - max = min; - i++; - } while (min == NODATA && i < nrMeteoPoints); - - while (i < nrMeteoPoints) - { - value = meteoPoints[i].getMeteoPointValueD(myDate, myVar); - if (value != NODATA) - { - if (value < min) - min = value; - if (value > max) - max = value; - } - i++; - } } else if (myFreq == hourly) { if (myVar != airTemperature) return false; + } + else + { + return false; + } - do { - min = meteoPoints[i].getMeteoPointValueH(myDate, myHour, 0, myVar); - max = min; - i++; - } while (min == NODATA); + Crit3DDate myDate = getCrit3DDate(this->getCurrentDate()); + int myHour = this->getCurrentHour(); + float currentMin = NODATA; + float currentMax = NODATA; + float value = NODATA; - for (int i = 0; i < nrMeteoPoints; i++) + for (int i = 0; i < nrMeteoPoints; i++) + { + if (myFreq == daily) + { + value = meteoPoints[i].getMeteoPointValueD(myDate, myVar); + } + else if (myFreq == hourly) { value = meteoPoints[i].getMeteoPointValueH(myDate, myHour, 0, myVar); - if (value != NODATA) + } + if (value != NODATA) + { + if (value < currentMin || currentMin == NODATA) + { + currentMin = value; + } + if (value > currentMax || currentMax == NODATA) { - if (value < min) - min = value; - if (value > max) - max = value; + currentMax = value; } } } - if (min != NODATA && max != NODATA) - interpolationSettings.setMinMaxTemperature(min, max); + if (currentMin == NODATA || currentMax == NODATA) + { + return false; + } + interpolationSettings.setMinMaxTemperature(currentMin, currentMax); return true; } @@ -4569,7 +4562,7 @@ bool Project::waterTableImportLocation(QString csvFileName) } int wrongLines = 0; - if (! loadCsvRegistry(csvFileName, wellPoints, errorString, wrongLines)) + if (! loadWaterTableLocationCsv(csvFileName, wellPoints, errorString, wrongLines)) { logError(errorString); return false; @@ -4590,7 +4583,7 @@ bool Project::waterTableImportLocation(QString csvFileName) bool Project::waterTableImportDepths(QString csvDepths) { int wrongLines = 0; - if (! loadCsvDepths(csvDepths, wellPoints, quality->getWaterTableMaximumDepth(), errorString, wrongLines)) + if (! loadWaterTableDepthCsv(csvDepths, wellPoints, quality->getWaterTableMaximumDepth(), errorString, wrongLines)) { logError(errorString); return false; diff --git a/project/project.h b/project/project.h index 7c0f60f5..8a440705 100644 --- a/project/project.h +++ b/project/project.h @@ -277,7 +277,7 @@ void showMeteoWidgetGrid(std::string idCell, bool isAppend); void showProxyGraph(); void showLocalProxyGraph(gis::Crit3DGeoPoint myPoint, gis::Crit3DRasterGrid *myDataRaster); - bool findTempMinMax(meteoVariable myVar); + bool findTemperatureRange(meteoVariable myVar); void clearSelectedPoints(); void clearSelectedOutputPoints(); diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index 747c21a4..8d560513 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -5,36 +5,45 @@ #include -bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString &errorStr, int &wrongLines) +bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines) { errorStr = ""; wellList.clear(); - QFile myFile(csvRegistry); + QFile myFile(csvFileName); QList idList; QList errorList; int posId = 0; int posUtmx = 1; int posUtmy = 2; - int nFields = 3; - bool ok; + int nrRequiredFields = 3; + int validLines = 0; + bool ok; if (! myFile.open(QFile::ReadOnly | QFile::Text) ) { - errorStr = "csvFileName file does not exist"; + errorStr = "Csv file does not exist:\n" + csvFileName; return false; } else { QTextStream in(&myFile); - //skip header + + // check header QString line = in.readLine(); - while (!in.atEnd()) + QList headerItems = line.split(","); + if (headerItems.size() != nrRequiredFields) + { + errorStr = "Wrong data! Required well ID, utm X, utm Y."; + return false; + } + + while (! in.atEnd()) { line = in.readLine(); QList items = line.split(","); items.removeAll({}); - if (items.size() &wellList, QString & wrongLines++; continue; } + Well newWell; newWell.setId(id); newWell.setUtmX(utmX); newWell.setUtmY(utmY); wellList.push_back(newWell); + validLines++; } } myFile.close(); + if (validLines == 0) + { + errorStr = "Wrong wells location:\n" + csvFileName; + return false; + } + if (wrongLines > 0) { errorStr = "ID repeated or with invalid coordinates: " + errorList.join(","); @@ -84,35 +101,45 @@ bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString & } -bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) +bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, + int waterTableMaximumDepth, QString &errorStr, int &wrongLines) { - QFile myFile(csvDepths); + errorStr = ""; + QFile myFile(csvFileName); QList errorList; int posId = 0; int posDate = 1; int posDepth = 2; - int nFields = 3; + int nrRequiredFields = 3; + int validLines = 0; bool ok; - errorStr = ""; if (! myFile.open(QFile::ReadOnly | QFile::Text) ) { - errorStr = "csvFileName file does not exist"; + errorStr = "Csv file does not exist:\n" + csvFileName; return false; } else { QTextStream in(&myFile); - //skip header + + // check header QString line = in.readLine(); + QList headerItems = line.split(","); + if (headerItems.size() != nrRequiredFields) + { + errorStr = "Wrong data! Required well ID, date, depth."; + return false; + } + while (!in.atEnd()) { line = in.readLine(); QList items = line.split(","); items.removeAll({}); - if (items.size() < nFields) + if (items.size() < nrRequiredFields) { errorList.append(line); wrongLines++; @@ -156,10 +183,17 @@ bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTabl } wellList[index].insertData(date, value); + validLines++; } } myFile.close(); + if (validLines == 0) + { + errorStr = "Wrong water table depth:\n" + csvFileName; + return false; + } + if (wrongLines > 0) { errorStr = "ID not existing or with invalid data or value:\n" + errorList.join("\n"); diff --git a/waterTable/importData.h b/waterTable/importData.h index 1b5a433d..369c6ae5 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -6,8 +6,8 @@ #include "well.h" #endif -bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString &errorStr, int &wrongLines); -bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); +bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines); +bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H From e3750748b4daf60b98781e2ac4534eba02b92e09 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 29 May 2024 20:25:07 +0200 Subject: [PATCH 013/179] fix watertable --- project/project.cpp | 11 ++++-- waterTable/waterTable.cpp | 57 +++++++++++++++++------------- waterTable/waterTable.h | 6 ++-- waterTable/waterTableChartView.cpp | 44 ++++++++++++----------- 4 files changed, 67 insertions(+), 51 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 8f8727d7..7f9aea26 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4611,6 +4611,7 @@ bool Project::computeSingleWell(int indexWell) double wellUtmX = wellPoints[indexWell].getUtmX(); double wellUtmY = wellPoints[indexWell].getUtmY(); Crit3DMeteoPoint linkedMeteoPoint; + if (this->meteoGridDbHandler != nullptr) { isMeteoGridLoaded = true; @@ -4624,6 +4625,7 @@ bool Project::computeSingleWell(int indexWell) logError(ERROR_STR_MISSING_POINT_GRID); return false; } + if (!assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) { logError("Missing near weather data"); @@ -4634,10 +4636,13 @@ bool Project::computeSingleWell(int indexWell) logError("Missing near weather data"); return false; } - int maxNrDays = 730; // attualmente fisso + + int maxNrDays = 730; // attualmente fisso (2 anni) WaterTable waterTable(&linkedMeteoPoint, *meteoSettings, gisSettings); - waterTable.computeWaterTable(wellPoints[indexWell], maxNrDays); - waterTable.viewWaterTableSeries(); // prepare series to show + + waterTable.computeWaterTableParameters(wellPoints[indexWell], maxNrDays); + waterTable.computeWaterTableSeries(); + waterTableList.push_back(waterTable); return true; } diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 9fc3730e..a1d20924 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -116,7 +116,7 @@ void WaterTable::initializeWaterTable(Well myWell) } -bool WaterTable::computeWaterTable(Well myWell, int maxNrDays) +bool WaterTable::computeWaterTableParameters(Well myWell, int maxNrDays) { if (myWell.getObsDepthNr() == 0) { @@ -239,7 +239,8 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) float b; float myR2; - for (int nrDays = 90; nrDays <= maxNrDays; nrDays=nrDays+10) + maxNrDays = std::max(90, maxNrDays); + for (int nrDays = 90; nrDays <= maxNrDays; nrDays = nrDays+5) { myCWBSum.clear(); myObsWT.clear(); @@ -256,6 +257,7 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) myObsWT.push_back(myValue); } } + statistics::linearRegression(myCWBSum, myObsWT, int(myCWBSum.size()), false, &a, &b, &myR2); if (myR2 > bestR2) { @@ -265,6 +267,7 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) bestAlfaCoeff = b; } } + if (bestR2 > 0) { nrObsData = int(myObsWT.size()); @@ -433,7 +436,6 @@ float WaterTable::getWaterTableClimate(QDate myDate) bool WaterTable::computeWaterTableClimate(QDate currentDate, int yearFrom, int yearTo, float* myValue) { - *myValue = NODATA; int nrYears = yearTo - yearFrom + 1; @@ -446,7 +448,7 @@ bool WaterTable::computeWaterTableClimate(QDate currentDate, int yearFrom, int y for (int myYear = yearFrom; myYear <= yearTo; myYear++) { QDate myDate(myYear, currentDate.month(), currentDate.day()); - if (getWaterTableHindcast(myDate, &myDepth, &myDelta, &myDeltaDays)) + if (getWaterTableInterpolation(myDate, &myDepth, &myDelta, &myDeltaDays)) { nrValidYears = nrValidYears + 1; sumDepth = sumDepth + myDepth; @@ -465,28 +467,28 @@ bool WaterTable::computeWaterTableClimate(QDate currentDate, int yearFrom, int y } // restituisce il dato interpolato considerando i dati osservati -bool WaterTable::getWaterTableHindcast(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays) +bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays) { *myValue = NODATA; *myDelta = NODATA; - bool getWaterTableHindcast = false; - if (!myDate.isValid()) + + if (! myDate.isValid()) { error = "Wrong date"; - return getWaterTableHindcast; + return false; } - if (!isCWBEquationReady) + if (! isCWBEquationReady) { - return getWaterTableHindcast; + return false; } // first assessment float myWT_computation = getWaterTableDaily(myDate); if (myWT_computation == NODATA) { - return getWaterTableHindcast; + return false; } + // da qui in avanti รจ true (ha almeno il dato di stima) - getWaterTableHindcast = true; float myWT = NODATA; float previousDz = NODATA; float nextDz = NODATA; @@ -603,10 +605,11 @@ bool WaterTable::getWaterTableHindcast(QDate myDate, float* myValue, float* myDe } *myValue = myWT_computation + *myDelta; - return getWaterTableHindcast; + return true; } -void WaterTable::viewWaterTableSeries() + +void WaterTable::computeWaterTableSeries() { QMap myDepths = well.getObsDepths(); QMapIterator it(myDepths); @@ -614,20 +617,26 @@ void WaterTable::viewWaterTableSeries() myDates.clear(); myHindcastSeries.clear(); myInterpolateSeries.clear(); - float myDepth; float myDelta; int myDeltaDays; - int numValues = well.getFirstDate().daysTo(lastMeteoDate) + 1; - for (int i = 0; i< numValues; i++) + QDate firstObsDate = well.getFirstDate(); + int numValues = firstObsDate.daysTo(lastMeteoDate) + 1; + for (int i = 0; i < numValues; i++) { - QDate myDate = well.getFirstDate().addDays(i); + QDate myDate = firstObsDate.addDays(i); myDates.push_back(myDate); - //float computedValue = getWaterTableDaily(myDate.addDays(-1)); // LC in vb toglie un giorno ma non si capisce il motivo - float computedValue = getWaterTableDaily(myDate); - myHindcastSeries.push_back(computedValue); - //getWaterTableHindcast(myDate.addDays(-1), &myDepth, &myDelta, &myDeltaDays); // LC in vb toglie un giorno ma non si capisce il motivo - getWaterTableHindcast(myDate, &myDepth, &myDelta, &myDeltaDays); - myInterpolateSeries.push_back(myDepth); + + float myDepth = getWaterTableDaily(myDate); + myHindcastSeries.push_back(myDepth); + + if (getWaterTableInterpolation(myDate, &myDepth, &myDelta, &myDeltaDays)) + { + myInterpolateSeries.push_back(myDepth); + } + else + { + myInterpolateSeries.push_back(NODATA); + } } } diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 1c64e31d..0fdedbe1 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -17,7 +17,7 @@ class WaterTable QDate getFirstDateWell(); QDate getLastDateWell(); void initializeWaterTable(Well myWell); - bool computeWaterTable(Well myWell, int maxNrDays); + bool computeWaterTableParameters(Well myWell, int maxNrDays); bool computeWTClimate(); bool computeETP_allSeries(); bool computeCWBCorrelation(int maxNrDays); @@ -26,8 +26,8 @@ class WaterTable float getWaterTableDaily(QDate myDate); float getWaterTableClimate(QDate myDate); bool computeWaterTableClimate(QDate currentDate, int yearFrom, int yearTo, float* myValue); - bool getWaterTableHindcast(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays); - void viewWaterTableSeries(); + bool getWaterTableInterpolation(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays); + void computeWaterTableSeries(); QString getError() const; float getAlpha() const; diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index 5d5b4faf..ee800815 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -34,36 +34,38 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : void WaterTableChartView::draw(std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths) { + axisY->setMax(300); + axisY->setMin(0); + axisY->setLabelFormat("%d"); + axisY->setTickCount(16); + + QDateTime firstDate; + firstDate.setDate(myDates[0]); + QDateTime lastDate; + lastDate.setDate(myDates[myDates.size()-1]); + + axisX->setRange(firstDate, lastDate); + axisX->setTickCount(15); + int nDays = int(myDates.size()); - QDateTime myDateTime; - myDateTime.setTime(QTime(0,0,0)); + QDateTime currentDateTime; for (int day = 0; day < nDays; day++) { - myDateTime.setDate(myDates[day]); - hindcastSeries->append(myDateTime.toMSecsSinceEpoch(), myHindcastSeries[day]); - interpolationSeries->append(myDateTime.toMSecsSinceEpoch(), myInterpolateSeries[day]); + currentDateTime.setDate(myDates[day]); + hindcastSeries->append(currentDateTime.toMSecsSinceEpoch(), myHindcastSeries[day]); + interpolationSeries->append(currentDateTime.toMSecsSinceEpoch(), myInterpolateSeries[day]); if(obsDepths.contains(myDates[day])) { int myDepth = obsDepths[myDates[day]]; - obsDepthSeries->append(myDateTime.toMSecsSinceEpoch(), myDepth); + obsDepthSeries->append(currentDateTime.toMSecsSinceEpoch(), myDepth); + } + else + { + obsDepthSeries->append(currentDateTime.toMSecsSinceEpoch(), -1); } } - - axisY->setMax(300); - axisY->setMin(0); - axisY->setLabelFormat("%d"); - axisY->setTickCount(16); - axisX->setTickCount(15); - QDateTime firstDateTime; - firstDateTime.setDate(myDates[0]); - firstDateTime.setTime(QTime(0,0,0)); - QDateTime lastDateTime; - lastDateTime.setDate(myDates[myDates.size()-1]); - lastDateTime.setTime(QTime(0,0,0)); - axisX->setRange(firstDateTime, lastDateTime); - chart()->addSeries(obsDepthSeries); chart()->addSeries(hindcastSeries); chart()->addSeries(interpolationSeries); @@ -77,9 +79,9 @@ void WaterTableChartView::draw(std::vector myDates, std::vector my marker->series()->setVisible(true); QObject::connect(marker, &QLegendMarker::clicked, this, &WaterTableChartView::handleMarkerClicked); } - return; } + void WaterTableChartView::tooltipObsDepthSeries(QPointF point, bool state) { From 8929fbbdee60b68bbe3270df8045ddf9adca4f25 Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Thu, 30 May 2024 12:47:26 +0200 Subject: [PATCH 014/179] aggiustamento parsing --- weatherGenerator/parserXML.cpp | 6 ++++-- weatherGenerator/weatherGenerator.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/weatherGenerator/parserXML.cpp b/weatherGenerator/parserXML.cpp index f8775f41..2ad0912e 100644 --- a/weatherGenerator/parserXML.cpp +++ b/weatherGenerator/parserXML.cpp @@ -437,6 +437,7 @@ bool parseXMLScenario(const QString &xmlFileName, XMLScenarioAnomaly &XMLAnomaly else if (ancestor.toElement().tagName().toUpper() == "PERIOD") { child = ancestor.firstChild(); + counterVar = 0; while(! child.isNull()) { myTag = child.toElement().tagName().toUpper(); @@ -452,7 +453,7 @@ bool parseXMLScenario(const QString &xmlFileName, XMLScenarioAnomaly &XMLAnomaly if (myTag == "VAR") { secondChild = child.firstChild(); - counterVar = 0; + while(! secondChild.isNull()) { mySecondTag = secondChild.toElement().tagName().toUpper(); @@ -478,8 +479,9 @@ bool parseXMLScenario(const QString &xmlFileName, XMLScenarioAnomaly &XMLAnomaly } secondChild = secondChild.nextSibling(); - counterVar++; + } + counterVar++; } child = child.nextSibling(); } diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 61cb095d..9d75c65d 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -673,9 +673,9 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, // loop for all XMLValuesList (Tmin, Tmax, TminVar, TmaxVar, Prec3M, Wetdays) for (i = 0; i < 4; i++) { - /*if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") + if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") { - myVar = XMLAnomaly->forecast[i].type.toUpper(); + /*myVar = XMLAnomaly->forecast[i].type.toUpper(); result = false; if (XMLAnomaly->forecast[i].value[modelIndex] != nullptr) @@ -709,8 +709,8 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, { qDebug() << "wrong anomaly: " + myVar; return false; - } - }*/ + }*/ + } } /* DEBUG From 936bbbc518846a10f82db0aa398972ac81629a8d Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 30 May 2024 13:04:05 +0200 Subject: [PATCH 015/179] fix merge --- project/project.cpp | 15 ++++----------- waterTable/importData.h | 7 +------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index e25a67fa..6b102f39 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4636,15 +4636,7 @@ bool Project::computeSingleWell(int indexWell) logError("Missing near weather data"); return false; } -<<<<<<< HEAD - int maxNrDays = 730; // attualmente fisso (2 anni) - WaterTable waterTable(&linkedMeteoPoint, *meteoSettings, gisSettings); - - waterTable.computeWaterTableParameters(wellPoints[indexWell], maxNrDays); - waterTable.computeWaterTableSeries(); - -======= int maxNrDays = 730; // attualmente fisso std::vector inputTMin; @@ -4661,13 +4653,14 @@ bool Project::computeSingleWell(int indexWell) inputTMax.push_back(Tmax); inputPrec.push_back(prec); } + QDate firstDate(linkedMeteoPoint.getFirstDailyData().year, linkedMeteoPoint.getFirstDailyData().month, linkedMeteoPoint.getFirstDailyData().day); QDate lastDate(linkedMeteoPoint.getLastDailyData().year, linkedMeteoPoint.getLastDailyData().month, linkedMeteoPoint.getLastDailyData().day); WaterTable waterTable(inputTMin, inputTMax, inputPrec, firstDate, lastDate, *meteoSettings, gisSettings); - waterTable.computeWaterTable(wellPoints[indexWell], maxNrDays); - waterTable.viewWaterTableSeries(); // prepare series to show ->>>>>>> 2a84db442537ad935d81f540ab67574523de1a13 + waterTable.computeWaterTableParameters(wellPoints[indexWell], maxNrDays); + waterTable.computeWaterTableSeries(); // prepare series to show + waterTableList.push_back(waterTable); return true; } diff --git a/waterTable/importData.h b/waterTable/importData.h index 73a033b8..165a7470 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -6,15 +6,10 @@ #include "well.h" #endif -<<<<<<< HEAD bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines); bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); -======= -bool loadCsvRegistry(QString csvRegistry, std::vector &wellList, QString &errorStr, int &wrongLines); -bool loadCsvDepths(QString csvDepths, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); -bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines); ->>>>>>> 2a84db442537ad935d81f540ab67574523de1a13 + #endif // IMPORTDATA_H From 8d0076371d60840ea0d687631f2803c97593c06b Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 30 May 2024 14:59:48 +0200 Subject: [PATCH 016/179] fix wg --- weatherGenerator/weatherGenerator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 9d75c65d..058c4e38 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -671,7 +671,7 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, bool result; // loop for all XMLValuesList (Tmin, Tmax, TminVar, TmaxVar, Prec3M, Wetdays) - for (i = 0; i < 4; i++) + /*for (i = 0; i < 4; i++) { if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") { @@ -709,9 +709,9 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, { qDebug() << "wrong anomaly: " + myVar; return false; - }*/ + } } - } + }*/ /* DEBUG QString anomaly="anomaly.txt"; From 82646100063f8e880c8f7c3a9fe7e728c6495e1b Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Thu, 30 May 2024 15:14:02 +0200 Subject: [PATCH 017/179] .. --- weatherGenerator/weatherGenerator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 058c4e38..75e08c93 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -671,9 +671,9 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, bool result; // loop for all XMLValuesList (Tmin, Tmax, TminVar, TmaxVar, Prec3M, Wetdays) - /*for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { - if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") + /*if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") { /*myVar = XMLAnomaly->forecast[i].type.toUpper(); result = false; @@ -710,8 +710,8 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, qDebug() << "wrong anomaly: " + myVar; return false; } - } - }*/ + }*/ + } /* DEBUG QString anomaly="anomaly.txt"; From 5d3fca2f2f090bca68f326e2f4646904067ac9b1 Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Thu, 30 May 2024 15:21:36 +0200 Subject: [PATCH 018/179] fix conflict --- waterTable/importData.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/waterTable/importData.h b/waterTable/importData.h index 165a7470..9b75c9c0 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -8,8 +8,7 @@ bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines); bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); -bool loadCsvDepthsSingleWell(QString csvDepths, Well well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); - +bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H From f0d09744db9a5a632fdcaaaa69a0c83655f1c7b3 Mon Sep 17 00:00:00 2001 From: cate-to Date: Thu, 30 May 2024 17:13:01 +0200 Subject: [PATCH 019/179] separazione proxy --- gis/gis.cpp | 8 +- gis/gis.h | 2 +- interpolation/interpolation.cpp | 347 +++++++++++++++++++----- interpolation/interpolation.h | 10 +- interpolation/interpolationConstants.h | 2 - interpolation/interpolationSettings.cpp | 68 ++++- interpolation/interpolationSettings.h | 15 +- mathFunctions/furtherMathFunctions.cpp | 43 +-- mathFunctions/furtherMathFunctions.h | 2 + project/dialogInterpolation.cpp | 4 +- project/interpolationCmd.cpp | 2 +- project/project.cpp | 62 ++++- proxyWidget/localProxyWidget.cpp | 42 +-- 13 files changed, 451 insertions(+), 156 deletions(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index 3d02f789..6acbad89 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -517,7 +517,7 @@ namespace gis return true; } - std::vector> Crit3DRasterGrid::prepareParameters(int row, int col) + std::vector> Crit3DRasterGrid::prepareParameters(int row, int col, unsigned int activeProxyNr) { std::vector> tempProxyVector; std::vector tempParVector; @@ -538,14 +538,13 @@ namespace gis for (j = col-1; j < col+2; j++) { index = i * header->nrCols + j; - if (index >= 0 && index < parametersCell.size() && !parametersCell[index].fittingParameters.empty() && (i != row || j !=col)) + if (index >= 0 && index < parametersCell.size() && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) findFirst = 1; if (findFirst==1) break; } if (findFirst==1) break; } - //starting from firt full cell, look at the remaining ones and calculate all the average parameter values for (k = 0; k < parametersCell[index].fittingParameters.size(); k++) { for (l = 0; l < parametersCell[index].fittingParameters[k].size(); l++) @@ -557,14 +556,13 @@ namespace gis for (int m = j; m < col+2; m++) { index = h * header->nrCols + m; - if (index >= 0 && index < parametersCell.size() && !parametersCell[index].fittingParameters.empty() && (i != row || j !=col)) + if (index >= 0 && index < parametersCell.size() && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) { avg += parametersCell[index].fittingParameters[k][l]; counter++; } } } - //push back the vector of averages tempParVector.push_back(avg/counter); index = i*header->nrCols+j; } diff --git a/gis/gis.h b/gis/gis.h index 496c4327..e604e2a5 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -191,7 +191,7 @@ float getValueFromXY(double x, double y) const; std::vector> getParametersFromRowCol(int row, int col); bool setParametersForRowCol(int row, int col, std::vector> parameters); - std::vector> prepareParameters(int row, int col); + std::vector> prepareParameters(int row, int col, unsigned int activeProxyNr); Crit3DTime getMapTime() const; void setMapTime(const Crit3DTime &value); diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 089ef9f8..cd02bf38 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1188,36 +1188,25 @@ void detrendPoints(std::vector &myPoints, Crit3DI float retrend(meteoVariable myVar, vector myProxyValues, Crit3DInterpolationSettings* mySettings) { - if (! getUseDetrendingVar(myVar)) return 0.; double retrendValue = 0.; double myProxyValue; Crit3DProxy* myProxy = nullptr; - Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); float proxySlope; + Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); if (mySettings->getUseMultipleDetrending()) { std::vector activeProxyValues; - if (getActiveProxyValues(mySettings, myProxyValues, activeProxyValues)) + if (getActiveProxyValues(myCombination, myProxyValues, activeProxyValues)) { std::vector&)>> myFunc = mySettings->getFittingFunction(); std::vector > fittingParameters = mySettings->getFittingParameters(); if (myFunc.size() > 0 && fittingParameters.size() > 0) retrendValue = float(functionSum(myFunc, activeProxyValues, fittingParameters)); - - for (int pos=0; pos < int(mySettings->getProxyNr()); pos++) //can be skipped if altitude is always first proxy - { - if (getProxyPragaName(mySettings->getProxy(pos)->getName()) == proxyHeight) - { - if (!mySettings->getProxy(pos)->getIsSignificant()) - retrendValue = 0.; - break; - } - } } } else @@ -1412,12 +1401,9 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati mySettings->getProxy(i)->setFittingParametersRange(tempParam); } else - { mySettings->getProxy(i)->setFittingFunctionName(linear); - mySettings->getProxy(i)->setFittingParametersRange({0,100}); - } } - return 1; + return true; } bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings, @@ -1426,31 +1412,49 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 std::vector > ¶mDelta, std::vector > ¶mFirstGuess, std::string &errorStr) { + bool isPreviousParam = false; + + if (myCombination.getProxySize() > 0) + { + if (myCombination.isProxyActive(0)) //siamo nel caso elevation + { + //controlla se ci sono parametri salvati per l'elevation + if (paramFirstGuess.size() > 0) + { + if (paramFirstGuess[0].size() > 0) + isPreviousParam = true; + } + } + else + { + if (paramFirstGuess.size() > 0) //no? TODO + isPreviousParam = true; + } + } + const double RATIO_DELTA = 1000; - bool isPreviousParam = !paramFirstGuess.empty(); for (unsigned i=0; i < myCombination.getProxySize(); i++) - if (mySettings->getProxy(i)->getIsSignificant()) + if (myCombination.isProxyActive(i) && myCombination.isProxySignificant(i)) { if (getProxyPragaName(mySettings->getProxy(i)->getName()) == proxyHeight) { - if (mySettings->getChosenElevationFunction() == frei) - myFunc.push_back(lapseRateFrei); - else if (mySettings->getChosenElevationFunction() == piecewiseTwo) + if (mySettings->getChosenElevationFunction() == piecewiseTwo) myFunc.push_back(lapseRatePiecewise_two); - else if (mySettings->getChosenElevationFunction() == piecewiseThree) - myFunc.push_back(lapseRatePiecewiseForInterpolation); else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) myFunc.push_back(lapseRatePiecewiseFree); else if (mySettings->getChosenElevationFunction() == piecewiseThreeSlope) myFunc.push_back(lapseRatePiecewiseThree_withSlope); else if (mySettings->getChosenElevationFunction() == freiFree) myFunc.push_back(lapseRateFreiFree); + else + { + errorStr = "Missing or wrong fitting function for proxy: " + mySettings->getProxy(i)->getName(); + return false; + } } else - { - myFunc.push_back(functionLinear); - } + myFunc.push_back(functionLinear_intercept); std::vector myParam = mySettings->getProxy(i)->getFittingParametersRange(); unsigned int nrParam = unsigned(myParam.size() / 2); @@ -1504,27 +1508,13 @@ bool setAllFittingParameters(Crit3DProxyCombination myCombination, Crit3DInterpo double min = mySettings->getMinMaxTemperature()[0]; double max = mySettings->getMinMaxTemperature()[1]; std::vector tempParam; - if (mySettings->getChosenElevationFunction() == frei) - { - myFunc.push_back(lapseRateFrei); - mySettings->getProxy(i)->setFittingFunctionName(frei); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {min, 0, -10, -200, 0.1, max+10, 0.006, 10, 1800, 1000}; - } - else if (mySettings->getChosenElevationFunction() == piecewiseTwo) + if (mySettings->getChosenElevationFunction() == piecewiseTwo) { myFunc.push_back(lapseRatePiecewise_two); mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 0, -0.006, 1800, max+2, 0.01, 0}; } - else if (mySettings->getChosenElevationFunction() == piecewiseThree) - { - myFunc.push_back(lapseRatePiecewiseForInterpolation); - mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 100, 0, -0.006, 1800, max+2, 1000, (max-min-2), 0}; - } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { myFunc.push_back(lapseRatePiecewiseFree); @@ -1617,16 +1607,196 @@ std::vector getfittingParameters(Crit3DProxyCombination myCombination, return myParam; } +bool multipleDetrendingMain(std::vector &myPoints, + Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr) +{ + std::vector> otherParameters = mySettings->getFittingParameters(); + std::vector > elevationParameters = mySettings->getFittingParameters(); + size_t paramSize = mySettings->getFittingParameters().size(); + mySettings->clearFitting(); + + if (mySettings->getCurrentCombination().isProxyActive(0)) + { + if (elevationParameters.size() > 0) //forse meglio fare vettore con dimensione = nrProxy (attivi) + { + while (elevationParameters.back().size() < 5) + elevationParameters.pop_back(); + + if (otherParameters[1].size() > 2) + { + for (int i = 0; i < (paramSize - 1); i++) + otherParameters[i] = otherParameters[i+1]; + otherParameters.pop_back(); + } + } -bool multipleDetrending(std::vector &myPoints, + Crit3DProxyCombination elevationCombination; + elevationCombination.resetCombination(mySettings->getSelectedCombination().getProxySize()); + elevationCombination.setProxyActive(0, true); + + if (!multipleDetrendingElevation(elevationCombination, elevationParameters, myPoints, mySettings, myVar, errorStr)) + return true; + } + + Crit3DProxyCombination othersCombination = mySettings->getSelectedCombination(); + othersCombination.setProxyActive(0,false); + + if (!multipleDetrending(othersCombination, otherParameters, myPoints, mySettings, myVar, errorStr)) + return true; + + return true; + +} + +bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, std::vector> parameters, std::vector &myPoints, Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr) { - std::vector > parameters = mySettings->getFittingParameters(); - mySettings->clearFitting(); if (! getUseDetrendingVar(myVar)) return true; + int pos = 0; + Crit3DProxy* elevationProxy = mySettings->getProxy(pos); + + // proxy spatial variability (1st step) + double avg, stdDev; + unsigned validNr; + validNr = 0; + + if (proxyValidity(myPoints, pos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + { + elevationCombination.setProxySignificant(pos, true); + Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); + myCombination.setProxySignificant(pos, true); + mySettings->setCurrentCombination(myCombination); + elevationProxy->setIsSignificant(true); + } + else + { + elevationCombination.setProxySignificant(pos, false); + Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); + mySettings->setCurrentCombination(myCombination); + mySettings->getProxy(pos)->setIsSignificant(false); + return true; + } + + // exclude points with incomplete proxies + unsigned i; + bool isValid; + float proxyValue; + vector::iterator it = myPoints.begin(); + + while (it != myPoints.end()) + { + isValid = true; + if (elevationProxy->getIsSignificant()) + { + proxyValue = it->getProxyValue(pos); + if (proxyValue == NODATA) + { + isValid = false; + break; + } + } + + if (! isValid) + it = myPoints.erase(it); + else + it++; + } + + // proxy spatial variability (2nd step) + if (proxyValidity(myPoints, pos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + { + elevationCombination.setProxySignificant(pos, true); + Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); + myCombination.setProxySignificant(pos, true); + mySettings->setCurrentCombination(myCombination); + elevationProxy->setIsSignificant(true); + } + else + { + elevationCombination.setProxySignificant(pos, false); + Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); + mySettings->setCurrentCombination(myCombination); + elevationProxy->setIsSignificant(false); + return true; + } + + // filling vectors + std::vector predictors; + std::vector predictands; + std::vector weights; + + for (i=0; i < myPoints.size(); i++) + { + predictors.push_back(myPoints[i].getProxyValue(pos)); + predictands.push_back(myPoints[i].value); + weights.push_back(myPoints[i].regressionWeight); + } + + if (mySettings->getUseLocalDetrending() && myPoints.size() < mySettings->getMinPointsLocalDetrending()) + { + elevationProxy->setIsSignificant(false); + Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); + mySettings->setCurrentCombination(myCombination); + return true; + } + + std::vector > parametersMin; + std::vector > parametersMax; + std::vector > parametersDelta; + //std::vector > parameters; + std::vector&)>> myFunc; + + unsigned int nrMaxStep = 20; + if (parameters.empty()) + nrMaxStep *= 10; + + if (! setAllFittingParameters_noRange(elevationCombination, mySettings, myFunc, parametersMin, parametersMax, + parametersDelta, parameters, errorStr)) + { + return false; + } + + auto func = myFunc[pos].target&)>(); + + if (!func) + { + errorStr = "Wrong or missing fitting function for proxy: elevation."; + return false; + } + + // multiple non linear fitting + interpolation::bestFittingMarquardt_nDimension_singleFunction(*func, nrMaxStep, 4, parametersMin[pos], parametersMax[pos], parameters[pos], parametersDelta[pos], + 100, 0.005, 0.002, predictors, predictands, weights); + + mySettings->setFittingFunction(myFunc); + mySettings->setFittingParametersElevation(parameters[pos]); + - Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); + // detrending + float detrendValue; + for (i = 0; i < myPoints.size(); i++) + { + if ((elevationProxy->getIsSignificant())) + proxyValue = myPoints[i].getProxyValue(pos); + + detrendValue = float((*func)(proxyValue, parameters[pos])); + myPoints[i].value -= detrendValue; + } + + return true; +} + +bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector> parameters, std::vector &myPoints, + Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr) +{ + if (! getUseDetrendingVar(myVar)) return true; // verify predictors number unsigned nrPredictors = 0; @@ -1635,7 +1805,7 @@ bool multipleDetrending(std::vector &myPoints, int proxyNr = int(mySettings->getProxyNr()); for (int pos=0; pos < proxyNr; pos++) { - if (myCombination.isProxyActive(pos)) + if (othersCombination.isProxyActive(pos)) { myProxy = mySettings->getProxy(pos); myProxy->setIsSignificant(false); @@ -1653,10 +1823,26 @@ bool multipleDetrending(std::vector &myPoints, for (int pos=0; pos < proxyNr; pos++) { - if (myCombination.isProxyActive(pos) && proxyValidity(myPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) + if (othersCombination.isProxyActive(pos)) { - mySettings->getProxy(pos)->setIsSignificant(true); - validNr++; + if (proxyValidity(myPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) + { + othersCombination.setProxySignificant(pos, true); + Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); + myCombination.setProxySignificant(pos, true); + mySettings->setCurrentCombination(myCombination); + mySettings->getProxy(pos)->setIsSignificant(true); + validNr++; + } + else + { + othersCombination.setProxySignificant(pos, false); + Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); + mySettings->setCurrentCombination(myCombination); + mySettings->getProxy(pos)->setIsSignificant(false); + } } } @@ -1695,16 +1881,26 @@ bool multipleDetrending(std::vector &myPoints, validNr = 0; for (int pos=0; pos < proxyNr; pos++) { - if (myCombination.isProxyActive(pos) && proxyValidity(myPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) - { - mySettings->getProxy(pos)->setIsSignificant(true); - validNr++; - } - else + if (othersCombination.isProxyActive(pos)) { - mySettings->getProxy(pos)->setIsSignificant(false); - if (getProxyPragaName(mySettings->getProxy(pos)->getName()) == proxyHeight) - return true; + if (proxyValidity(myPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) + { + othersCombination.setProxySignificant(pos, true); + Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); + myCombination.setProxySignificant(pos, true); + mySettings->setCurrentCombination(myCombination); + mySettings->getProxy(pos)->setIsSignificant(true); + validNr++; + } + else + { + othersCombination.setProxySignificant(pos, false); + Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); + mySettings->setCurrentCombination(myCombination); + mySettings->getProxy(pos)->setIsSignificant(false); + } } } @@ -1720,7 +1916,7 @@ bool multipleDetrending(std::vector &myPoints, { rowPredictors.clear(); for (int pos=0; pos < proxyNr; pos++) - if ((mySettings->getProxy(pos)->getIsSignificant())) + if (othersCombination.isProxyActive(pos) && othersCombination.isProxySignificant(pos)) { proxyValue = myPoints[i].getProxyValue(pos); rowPredictors.push_back(proxyValue); @@ -1733,9 +1929,14 @@ bool multipleDetrending(std::vector &myPoints, if (mySettings->getUseLocalDetrending() && myPoints.size() < mySettings->getMinPointsLocalDetrending()) { - for (int pos = 0; pos < proxyNr; pos++) + Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); + for (int pos = 1; pos < proxyNr; pos++) + { + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); mySettings->getProxy(pos)->setIsSignificant(false); - + } + mySettings->setCurrentCombination(myCombination); return true; } @@ -1749,7 +1950,7 @@ bool multipleDetrending(std::vector &myPoints, if (parameters.empty()) nrMaxStep *= 10; - if (! setAllFittingParameters_noRange(myCombination, mySettings, myFunc, parametersMin, parametersMax, + if (! setAllFittingParameters_noRange(othersCombination, mySettings, myFunc, parametersMin, parametersMax, parametersDelta, parameters, errorStr)) { return false; @@ -1759,8 +1960,8 @@ bool multipleDetrending(std::vector &myPoints, interpolation::bestFittingMarquardt_nDimension(&functionSum, myFunc, nrMaxStep, 4, parametersMin, parametersMax, parameters, parametersDelta, 100, 0.005, 0.002, predictors, predictands, weights); - mySettings->setFittingFunction(myFunc); - mySettings->setFittingParameters(parameters); + mySettings->addFittingFunction(myFunc); + mySettings->addFittingParameters(parameters); std::vector proxyValues; @@ -1772,7 +1973,7 @@ bool multipleDetrending(std::vector &myPoints, for (int pos=0; pos < proxyNr; pos++) { - if ((mySettings->getProxy(pos)->getIsSignificant())) + if ((othersCombination.isProxyActive(pos)) && othersCombination.isProxySignificant(pos)) { proxyValue = myPoints[i].getProxyValue(pos); proxyValues.push_back(double(proxyValue)); @@ -1879,6 +2080,7 @@ bool preInterpolation(std::vector &myPoints, Crit Crit3DClimateParameters* myClimate, Crit3DMeteoPoint* myMeteoPoints, int nrMeteoPoints, meteoVariable myVar, Crit3DTime myTime, std::string &errorStr) { + if (myVar == precipitation || myVar == dailyPrecipitation) { int nrPrecNotNull; @@ -1895,10 +2097,10 @@ bool preInterpolation(std::vector &myPoints, Crit { if (mySettings->getUseMultipleDetrending()) { + mySettings->setCurrentCombination(mySettings->getSelectedCombination()); if (mySettings->getProxiesComplete()) { - mySettings->setCurrentCombination(mySettings->getSelectedCombination()); - if (! multipleDetrending(myPoints, mySettings, myVar, errorStr)) return false; + if (! multipleDetrendingMain(myPoints, mySettings, myVar, errorStr)) return false; } } else @@ -1971,19 +2173,18 @@ float interpolate(vector &myPoints, Crit3DInterpo } -bool getActiveProxyValues(Crit3DInterpolationSettings *mySettings, const std::vector &allProxyValues, std::vector &activeProxyValues) +bool getActiveProxyValues(Crit3DProxyCombination myCombination, const std::vector &allProxyValues, std::vector &activeProxyValues) { - Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); - if (allProxyValues.size() != mySettings->getProxyNr()) + if (allProxyValues.size() != myCombination.getProxySize()) return false; activeProxyValues.clear(); bool isComplete = true; - for (unsigned int i=0; i < mySettings->getProxyNr(); i++) - if (myCombination.isProxyActive(i) && mySettings->getProxy(i)->getIsSignificant()) + for (unsigned int i=0; i < myCombination.getProxySize(); i++) + if (myCombination.isProxyActive(i) && myCombination.isProxySignificant(i)) { activeProxyValues.push_back(allProxyValues[i]); if (allProxyValues[i] == NODATA) diff --git a/interpolation/interpolation.h b/interpolation/interpolation.h index b91da243..89dc5455 100644 --- a/interpolation/interpolation.h +++ b/interpolation/interpolation.h @@ -61,15 +61,21 @@ float interpolate(std::vector &myPoints, Crit3DInterpolationSettings *mySettings, Crit3DMeteoSettings *meteoSettings, meteoVariable myVar, float myX, float myY, float myZ, std::vector myProxyValues, bool excludeSupplemental); bool getProxyValuesXY(float x, float y, Crit3DInterpolationSettings* mySettings, std::vector &myValues); - bool getActiveProxyValues(Crit3DInterpolationSettings *mySettings, const std::vector &allProxyValues, std::vector &activeProxyValues); + bool getActiveProxyValues(Crit3DProxyCombination myCombination, const std::vector &allProxyValues, std::vector &activeProxyValues); void detrending(std::vector &myPoints, Crit3DProxyCombination myCombination, Crit3DInterpolationSettings *mySettings, Crit3DClimateParameters *myClimate, meteoVariable myVar, Crit3DTime myTime); - bool multipleDetrending(std::vector &myPoints, Crit3DInterpolationSettings* mySettings, + bool multipleDetrendingMain(std::vector &myPoints, + Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr); + + bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector > parameters, std::vector &myPoints, Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr); + bool multipleDetrendingElevation(Crit3DProxyCombination myCombination, std::vector > parameters, std::vector &myPoints, + Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr); + bool getUseDetrendingVar(meteoVariable myVar); bool isThermal(meteoVariable myVar); bool getUseTdVar(meteoVariable myVar); diff --git a/interpolation/interpolationConstants.h b/interpolation/interpolationConstants.h index b16c8ac2..9eda20ae 100644 --- a/interpolation/interpolationConstants.h +++ b/interpolation/interpolationConstants.h @@ -41,11 +41,9 @@ const std::map fittingFunctionNames = { { "Double piecewise", piecewiseTwo }, - { "Triple piecewise", piecewiseThree }, { "Triple piecewise (6 parameters)", piecewiseThreeFree}, { "Triple piecewise (5 parameters)", piecewiseThreeSlope}, { "Nonlinear Frei function (5 parameters)", frei }, - { "Nonlinear Frei function (6 parameters)", freiFree}, { "linear", linear } }; diff --git a/interpolation/interpolationSettings.cpp b/interpolation/interpolationSettings.cpp index 1024f5f5..2cc0a65b 100644 --- a/interpolation/interpolationSettings.cpp +++ b/interpolation/interpolationSettings.cpp @@ -139,9 +139,10 @@ void Crit3DInterpolationSettings::setSelectedCombination(const Crit3DProxyCombin selectedCombination = value; } -void Crit3DInterpolationSettings::setValueSelectedCombination(unsigned int index, bool isActive) +void Crit3DInterpolationSettings::setActiveSelectedCombination(unsigned int index, bool isActive) { selectedCombination.setProxyActive(index, isActive); + selectedCombination.setProxySignificant(index, false); } unsigned Crit3DInterpolationSettings::getIndexHeight() const @@ -164,6 +165,7 @@ Crit3DProxyCombination Crit3DInterpolationSettings::getCurrentCombination() cons return currentCombination; } + std::vector Crit3DInterpolationSettings::getCurrentProxy() const { return currentProxy; @@ -286,6 +288,22 @@ void Crit3DInterpolationSettings::setFittingParameters(const std::vector &newFittingParameters) +{ + if (fittingParameters.empty()) { + fittingParameters.push_back(newFittingParameters); + } else { + fittingParameters[0] = newFittingParameters; + } +} + +void Crit3DInterpolationSettings::addFittingParameters(const std::vector > &newFittingParameters) +{ + for (size_t i = 0; i < newFittingParameters.size(); ++i) { + fittingParameters.push_back(newFittingParameters[i]); + } +} + std::vector &)>> Crit3DInterpolationSettings::getFittingFunction() const { return fittingFunction; @@ -296,6 +314,12 @@ void Crit3DInterpolationSettings::setFittingFunction(const std::vector &)> > &newFittingFunction) +{ + for (int i = 0; i < newFittingFunction.size(); i ++) + fittingFunction.push_back(newFittingFunction[i]); +} + TFittingFunction Crit3DInterpolationSettings::getChosenElevationFunction() { return chosenElevationFunction; @@ -367,7 +391,7 @@ void Crit3DInterpolationSettings::initialize() meteoGridAggrMethod = aggrAverage; meteoGridUpscaleFromDem = true; indexHeight = unsigned(NODATA); - chosenElevationFunction = piecewiseThreeSlope; + chosenElevationFunction = piecewiseThreeFree; isKrigingReady = false; precipitationAllZero = false; @@ -737,7 +761,9 @@ void Crit3DInterpolationSettings::addProxy(Crit3DProxy myProxy, bool isActive_) setIndexHeight(int(currentProxy.size())-1); selectedCombination.addProxyActive(isActive_); + selectedCombination.addProxySignificant(false); optimalCombination.addProxyActive(isActive_); + optimalCombination.addProxySignificant(false); } std::string Crit3DInterpolationSettings::getProxyName(unsigned pos) @@ -761,9 +787,47 @@ Crit3DProxyCombination::Crit3DProxyCombination() void Crit3DProxyCombination::clear() { _isActiveList.clear(); + _isSignificantList.clear(); + _useThermalInversion = false; +} + +void Crit3DProxyCombination::resetCombination(unsigned int size) +{ + _isActiveList.resize(size); + _isSignificantList.resize(size); + for (unsigned int i = 0; i < size; i++) + { + setProxyActive(i, false); + setProxySignificant(i, false); + } _useThermalInversion = false; } +unsigned int Crit3DProxyCombination::getActiveProxySize() +{ + unsigned int size = 0; + for (unsigned int i = 0; i < getProxySize(); i++) + if (isProxyActive(i)) size++; + + return size; +} + +void Crit3DProxyCombination::setAllActiveToFalse() +{ + for (unsigned int i = 0; i < _isActiveList.size(); i++) + setProxyActive(i, false); + + return; +} + +void Crit3DProxyCombination::setAllSignificantToFalse() +{ + for (unsigned int i = 0; i < _isActiveList.size(); i++) + setProxySignificant(i, false); + + return; +} + bool Crit3DInterpolationSettings::getCombination(int combinationInteger, Crit3DProxyCombination &outCombination) { diff --git a/interpolation/interpolationSettings.h b/interpolation/interpolationSettings.h index c359154c..cce7c344 100644 --- a/interpolation/interpolationSettings.h +++ b/interpolation/interpolationSettings.h @@ -107,6 +107,7 @@ { private: std::vector _isActiveList; + std::vector _isSignificantList; bool _useThermalInversion; public: @@ -117,6 +118,15 @@ void setProxyActive(unsigned index, bool value) { _isActiveList[index] = value; } bool isProxyActive(unsigned index) { return _isActiveList[index]; } + void addProxySignificant(bool value) { _isSignificantList.push_back(value); } + void setProxySignificant(unsigned index, bool value) { _isSignificantList[index] = value; } + bool isProxySignificant(unsigned index) { return _isSignificantList[index]; } + + void resetCombination(unsigned int size); + void setAllActiveToFalse(); + void setAllSignificantToFalse(); + + unsigned int getActiveProxySize(); unsigned int getProxySize() const { return unsigned(_isActiveList.size()); } bool getUseThermalInversion() const { return _useThermalInversion; } @@ -224,7 +234,7 @@ void setOptimalCombination(const Crit3DProxyCombination &value); Crit3DProxyCombination getSelectedCombination() const; void setSelectedCombination(const Crit3DProxyCombination &value); - void setValueSelectedCombination(unsigned int index, bool isActive); + void setActiveSelectedCombination(unsigned int index, bool isActive); unsigned getIndexHeight() const; void setIndexHeight(unsigned value); Crit3DProxyCombination getCurrentCombination() const; @@ -254,8 +264,11 @@ std::vector> getFittingParameters() const; void setFittingParameters(const std::vector> &newFittingParameters); + void setFittingParametersElevation(const std::vector &newFittingParameters); + void addFittingParameters(const std::vector > &newFittingParameters); std::vector &)> > getFittingFunction() const; void setFittingFunction(const std::vector &)> > &newFittingFunction); + void addFittingFunction(const std::vector &)> > &newFittingFunction); bool getProxiesComplete() const; void setProxiesComplete(bool newProxiesComplete); void clearFitting(); diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 5d19e3fd..8498917c 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -123,34 +123,6 @@ double lapseRatePiecewise_three(double x, std::vector & par) } } -double lapseRatePiecewiseForInterpolation(double x, std::vector & par) -{ - // the piecewise line is parameterized as follows - // the line passes through A(par[0];par[1])and B(par[0]+par[2];par[1]+par[3]). par[4] is the slope of the 2 externals pieces - // "y = mx + q" piecewise function; - double xb; - par[2] = MAXVALUE(10, par[2]); - // par[2] means the delta between the two quotes. It must be positive. - xb = par[0]+par[2]; - if (x < par[0]) - { - //m = par[4];; - //q = par[1]-m*par[0]; - return par[4]*x + par[1]-par[4]*par[0]; - } - else if (x>xb) - { - //m = par[4]; - //q = (par[1]+par[3])-m*xb; - return par[4]*x + (par[1]+par[3])-par[4]*xb; - } - else - { - //m = ((par[1]+par[3])-par[1])/par[2]; - //q = par[1]-m*par[0]; - return (par[3]/par[2])*x + par[1]-(par[3])/par[2]*par[0]; - } -} double lapseRatePiecewiseThree_withSlope(double x, std::vector & par) { @@ -235,6 +207,11 @@ double functionLinear(double x, std::vector & par) return par[0] * x; } +double functionLinear_intercept(double x, std::vector & par) +{ + return par[0] * x + par[1]; +} + double multilinear(std::vector &x, std::vector &par) { if (par.size() != (x.size()+1)) @@ -1478,7 +1455,7 @@ namespace interpolation a[counterDim][counterDim] += lambda[i][k]*a[counterDim][counterDim]; for (j = counterDim+1; j < nrParametersTotal; j++) { - a[j][i] = a[i][j]; + a[j][counterDim] = a[counterDim][j]; } counterDim++; } @@ -1664,7 +1641,7 @@ namespace interpolation a[counterDim][counterDim] += lambda[i][k]; for (j = counterDim+1; j < nrParametersTotal; j++) { - a[j][i] = a[i][j]; + a[j][counterDim] = a[counterDim][j]; } counterDim++; } @@ -1803,7 +1780,7 @@ namespace interpolation a[counterDim][counterDim] += lambda[i][k]*a[counterDim][counterDim]; for (j = counterDim+1; j < nrParametersTotal; j++) { - a[j][i] = a[i][j]; + a[j][counterDim] = a[counterDim][j]; } counterDim++; } @@ -1939,7 +1916,7 @@ namespace interpolation } while(truncNormal <= 0.0 || truncNormal >= 1.0); parameters[j] = parametersMin[j] + (truncNormal)*(parametersMax[j]-parametersMin[j]); } - } while( (counter < nrTrials) && (R2 < 0.8) && (fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2) ); + } while( (counter < nrTrials) && !(R2Previous[0] > 0.8 && R2Previous[nrMinima-1] > 0.8) && (fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2) ); for (j=0; j &)> > &functions, std::vector& x, std::vector >& par); double functionSum_detrending(std::vector&)>>& functions, std::vector x, std::vector >& par); double functionLinear(double x, std::vector & par); + double functionLinear_intercept(double x, std::vector & par); + double multilinear(std::vector &x, std::vector &par); double lapseRatePiecewise_three(double x, std::vector & par); double lapseRatePiecewiseForInterpolation(double x, std::vector & par); double lapseRatePiecewiseFree(double x, std::vector & par); diff --git a/project/dialogInterpolation.cpp b/project/dialogInterpolation.cpp index 730dc72b..83ebe6fd 100644 --- a/project/dialogInterpolation.cpp +++ b/project/dialogInterpolation.cpp @@ -142,7 +142,7 @@ DialogInterpolation::DialogInterpolation(Project *myProject) std::map::const_iterator itElFunc; for (itElFunc = fittingFunctionNames.begin(); itElFunc != fittingFunctionNames.end(); ++itElFunc) { - if (itElFunc->first == "linear" || itElFunc->first == "Triple piecewise" || itElFunc->first == "Nonlinear Frei function (5 parameters)" || itElFunc->first == "Nonlinear Frei function (6 parameters)") + if (itElFunc->first == "linear" || itElFunc->first == "Nonlinear Frei function (5 parameters)") continue; elevationFunctionEdit.addItem(QString::fromStdString(itElFunc->first), QString::fromStdString(itElFunc->first)); } @@ -286,7 +286,7 @@ void DialogInterpolation::accept() } for (int i = 0; i < proxyListCheck->count(); i++) - _interpolationSettings->setValueSelectedCombination(unsigned(i), proxyListCheck->item(i)->checkState()); + _interpolationSettings->setActiveSelectedCombination(unsigned(i), proxyListCheck->item(i)->checkState()); QString algorithmString = algorithmEdit.itemData(algorithmEdit.currentIndex()).toString(); _interpolationSettings->setInterpolationMethod(interpolationMethodNames.at(algorithmString.toStdString())); diff --git a/project/interpolationCmd.cpp b/project/interpolationCmd.cpp index e32c1c89..5058e788 100644 --- a/project/interpolationCmd.cpp +++ b/project/interpolationCmd.cpp @@ -277,7 +277,7 @@ bool interpolationRaster(std::vector &myPoints, C gis::getUtmXYFromRowColSinglePrecision(*outputGrid, myRow, myCol, &myX, &myY); float myZ = raster.value[myRow][myCol]; if (mySettings->getUseLocalDetrending()) - mySettings->setFittingParameters(raster.prepareParameters(myRow, myCol)); + mySettings->setFittingParameters(raster.prepareParameters(myRow, myCol, mySettings->getSelectedCombination().getActiveProxySize())); if (! isEqual(myZ, outputGrid->header->flag)) { if (getUseDetrendingVar(myVar)) diff --git a/project/project.cpp b/project/project.cpp index 0d15387b..bf799ea6 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -694,7 +694,7 @@ bool Project::loadParameters(QString parametersFileName) if (getProxyPragaName(name_.toStdString()) == proxyHeight) nrParameters = 5; else - nrParameters = 1; + nrParameters = 2; myList = parameters->value("fitting_parameters").toStringList(); if (myList.size() != nrParameters*2 && myList.size() != (nrParameters-1)*2 && myList.size() != (nrParameters+1)*2) //TODO: change @@ -706,6 +706,62 @@ bool Project::loadParameters(QString parametersFileName) myProxy->setFittingParametersRange(StringListToDouble(myList)); } + /*if (getProxyPragaName(name_.toStdString()) == proxyHeight) + { + if (parameters->contains("fitting_function")) + { + std::string elevationFuction = parameters->value("fitting_function").toString().toStdString(); + if (fittingFunctionNames.find(elevationFuction) == fittingFunctionNames.end()) + { + errorString = "Unknown function for elevation. Choose between: piecewiseTwo, piecewiseThreeSlope, piecewiseThreeFree."; + return false; + } + else + interpolationSettings.setChosenElevationFunction(fittingFunctionNames.at(elevationFuction)); + + if (parameters->contains("fitting_parameters")) + { + unsigned int nrParameters; + + if (interpolationSettings.getChosenElevationFunction()== piecewiseTwo) + nrParameters = 4; + else if (interpolationSettings.getChosenElevationFunction()== piecewiseThreeSlope) + nrParameters = 5; + else if (interpolationSettings.getChosenElevationFunction()== piecewiseThreeFree) + nrParameters = 6; + + myList = parameters->value("fitting_parameters").toStringList(); + if (myList.size() != nrParameters*2) + { + errorString = "Wrong number of fitting parameters for proxy: " + name_; + return false; + } + + myProxy->setFittingParametersRange(StringListToDouble(myList)); + } + } + else + { + interpolationSettings.setChosenElevationFunction(piecewiseTwo); + } + } + else + { + if(parameters->contains("fitting_parameters")) + { + unsigned int nrParameters = 1; + + myList = parameters->value("fitting_parameters").toStringList(); + if (myList.size() != nrParameters*2) + { + errorString = "Wrong number of fitting parameters for proxy: " + name_; + return false; + } + + myProxy->setFittingParametersRange(StringListToDouble(myList)); + } + }*/ + if (! parameters->contains("active")) { errorString = "active not specified for proxy " + QString::fromStdString(myProxy->getName()); @@ -2369,7 +2425,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT std::vector subsetInterpolationPoints; localSelection(interpolationPoints, subsetInterpolationPoints, x, y, interpolationSettings); if (interpolationSettings.getUseLocalDetrending()) - interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col)); + interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col, myCombination.getActiveProxySize())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, meteoPoints, nrMeteoPoints, myVar, myTime, errorStdStr)) { @@ -2671,7 +2727,7 @@ bool Project::interpolationGrid(meteoVariable myVar, const Crit3DTime& myTime) { std::vector subsetInterpolationPoints; localSelection(interpolationPoints, subsetInterpolationPoints, myX, myY, interpolationSettings); - interpolationSettings.setFittingParameters(meteoGridDbHandler->meteoGrid()->dataMeteoGrid.prepareParameters(row, col)); + interpolationSettings.setFittingParameters(meteoGridDbHandler->meteoGrid()->dataMeteoGrid.prepareParameters(row, col, myCombination.getActiveProxySize())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, meteoPoints, nrMeteoPoints, myVar, myTime, errorStdStr)) { diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 74649656..6ac50693 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -619,19 +619,6 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) point_vector.append(point); } } - else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeFree) - { - std::vector xVector; - for (int m = xMin; m < xMax; m += 5) - xVector.push_back(m); - - for (int p = 0; p < xVector.size(); p++) - { - point.setX(xVector[p]); - point.setY(lapseRatePiecewiseFree(xVector[p], parameters[proxyPos])); - point_vector.append(point); - } - } else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeSlope) { std::vector xVector; @@ -683,27 +670,20 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) //TODO lineari /*xMin = getProxyMinValue(subsetInterpolationPoints, proxyPos); xMax = getProxyMaxValue(subsetInterpolationPoints, proxyPos); - bool isZeroIntercept = false; - if (!regressionGeneric(subsetInterpolationPoints, interpolationSettings, proxyPos, isZeroIntercept)) - { - return; - } - float regressionSlope = interpolationSettings->getProxy(proxyPos)->getRegressionSlope(); - float regressionIntercept = interpolationSettings->getProxy(proxyPos)->getRegressionIntercept(); + + float slope = parameters[proxyPos][0]; + float intercept = parameters[proxyPos][1]; + + float myY = intercept + slope * xMin; point.setX(xMin); - point.setY(regressionIntercept + regressionSlope * xMin); - point_vector.append(point); - point.setX(xMax); - point.setY(regressionIntercept + regressionSlope * xMax); + point.setY(myY); point_vector.append(point); - float regressionR2 = interpolationSettings->getProxy(proxyPos)->getRegressionR2(); - if (regressionR2 != NODATA) - { - r2.setText(QString("%1").arg(regressionR2, 0, 'f', 2)); - } - lapseRate.setText(QString("%1").arg(regressionSlope, 0, 'f', 2)); - */ } + myY = intercept + slope * xMax; + point.setX(xMax); + point.setY(myY); + point_vector.append(point);*/ + } chartView->drawModelLapseRate(point_vector); } } From b695c7d3ecc4e536c0d9e0d42c295d4f51e31e0d Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Thu, 30 May 2024 17:27:36 +0200 Subject: [PATCH 020/179] sistemazione anomalie scenario --- weatherGenerator/weatherGenerator.cpp | 78 ++++++++++++++------------- weatherGenerator/weatherGenerator.h | 2 +- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 75e08c93..65b49352 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -662,7 +662,7 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, return true; } -bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, int anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) +bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int anomalyMonth1, int anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) { unsigned int i = 0; QString myVar; @@ -671,48 +671,50 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, bool result; // loop for all XMLValuesList (Tmin, Tmax, TminVar, TmaxVar, Prec3M, Wetdays) - for (i = 0; i < 4; i++) + for (int iSeason=0;iSeason<4;iSeason++) { - /*if (XMLAnomaly->forecast[i].attribute.toUpper() == "ANOMALY") + for (i = 0; i < 4; i++) { - /*myVar = XMLAnomaly->forecast[i].type.toUpper(); - result = false; - - if (XMLAnomaly->forecast[i].value[modelIndex] != nullptr) - myValue = XMLAnomaly->forecast[i].value[modelIndex].toFloat(); - else - myValue = NODATA; - - if (int(myValue) != int(NODATA)) - { - if ( (myVar == "TMIN") || (myVar == "AVGTMIN") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmin, wGen.monthly.monthlyTmin); - else if ( (myVar == "TMAX") || (myVar == "AVGTMAX") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmax, wGen.monthly.monthlyTmax); - else if ( (myVar == "PREC3M") || (myVar == "PREC") ) - result = assignAnomalyPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.sumPrec, wGen.monthly.sumPrec); - else if ( (myVar == "WETDAYSFREQUENCY") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.fractionWetDays, wGen.monthly.fractionWetDays); - else if ( (myVar == "WETWETDAYSFREQUENCY") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.probabilityWetWet, wGen.monthly.probabilityWetWet); - else if ( (myVar == "DELTATMAXDRYWET") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.dw_Tmax, wGen.monthly.dw_Tmax); - } - else + if (XMLAnomaly->period[iSeason].seasonalScenarios[i].attribute.toUpper() == "ANOMALY") { - // not critical variables - if ((myVar == "DELTATMAXDRYWET") || (myVar == "WETWETDAYSFREQUENCY")) - result = true; - } - - if (result == false) - { - qDebug() << "wrong anomaly: " + myVar; - return false; + myVar = XMLAnomaly->period[iSeason].seasonalScenarios[i].type.toUpper(); + result = false; + //if (XMLAnomaly->forecast[i].value[modelIndex] != nullptr) + myValue = XMLAnomaly->period[iSeason].seasonalScenarios[i].value[modelIndex].toFloat(); + //else + //myValue = NODATA; + + if (int(myValue) != int(NODATA)) + { + /*if ( (myVar == "TMIN") || (myVar == "AVGTMIN") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmin, wGen.monthly.monthlyTmin); + else if ( (myVar == "TMAX") || (myVar == "AVGTMAX") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmax, wGen.monthly.monthlyTmax); + else if ( (myVar == "PREC3M") || (myVar == "PREC") ) + result = assignAnomalyPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.sumPrec, wGen.monthly.sumPrec); + else if ( (myVar == "WETDAYSFREQUENCY") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.fractionWetDays, wGen.monthly.fractionWetDays); + else if ( (myVar == "WETWETDAYSFREQUENCY") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.probabilityWetWet, wGen.monthly.probabilityWetWet); + else if ( (myVar == "DELTATMAXDRYWET") ) + result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.dw_Tmax, wGen.monthly.dw_Tmax); +*/ + } + /*else + { + // not critical variables + if ((myVar == "DELTATMAXDRYWET") || (myVar == "WETWETDAYSFREQUENCY")) + result = true; + } + + if (result == false) + { + qDebug() << "wrong anomaly: " + myVar; + return false; + }*/ } - }*/ + } } - /* DEBUG QString anomaly="anomaly.txt"; QFile file(anomaly); diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index 58f24fa0..fde0b9b6 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -108,7 +108,7 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, float* myWGMonthlyVarNoAnomaly, float* myWGMonthlyVar); - bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int anomalyMonth1, int anomalyMonth2, + bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int modelIndex, int anomalyMonth1, int anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen); bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, From e8e059c70f21703e3a58c7213b547293a8f7d56e Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 30 May 2024 18:51:15 +0200 Subject: [PATCH 021/179] update 3D --- mathFunctions/furtherMathFunctions.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 7adc995a..cfc8d339 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -1137,8 +1137,8 @@ namespace interpolation std::vector& weights) { int i,j; - int nrPredictors = parameters.size(); - int nrData = y.size(); + int nrPredictors = int(parameters.size()); + int nrData = int(y.size()); std::vector nrParameters(nrPredictors); int nrParametersTotal = 0; for (i=0; i& weights) { int i; - int nrPredictors = parameters.size(); - int nrData = y.size(); + int nrPredictors = int(parameters.size()); + int nrData = int(y.size()); double mySSE, diffSSE, newSSE; static double VFACTOR = 10; std::vector nrParameters(nrPredictors); From 3192da52ffc6787f121bec5c07f348d7a10656c0 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 31 May 2024 14:11:06 +0200 Subject: [PATCH 022/179] move spline to math functions --- mathFunctions/furtherMathFunctions.cpp | 106 +++++++++++++++++++++ mathFunctions/furtherMathFunctions.h | 5 +- waterTable/waterTable.cpp | 5 +- waterTable/waterTable.pro | 2 +- weatherGenerator/weatherGenerator.cpp | 124 ++----------------------- weatherGenerator/weatherGenerator.h | 2 - 6 files changed, 122 insertions(+), 122 deletions(-) diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index cfc8d339..746969ef 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -924,6 +924,112 @@ namespace interpolation } + /*! + * \brief Computes daily values starting from monthly averages using cubic spline + * \param monthlyAvg: vector of monthly averages (12 values) + * outputDailyValues: vector of interpolated daily values (366 values) + */ + void cubicSplineYearInterpolate(float *monthlyAvg, float *outputDailyValues) + { + double monthMid [16] = {-61, - 31, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396}; + + for (int iMonth=0; iMonth<16; iMonth++) + { + monthMid[iMonth] += 15; + } + + double* avgMonthlyAmountLarger = new double[16]; + for (int iMonth = 0; iMonth < 12; iMonth++) + { + avgMonthlyAmountLarger[iMonth+2] = double(monthlyAvg[iMonth]); + } + + avgMonthlyAmountLarger[0] = double(monthlyAvg[10]); + avgMonthlyAmountLarger[1] = double(monthlyAvg[11]); + avgMonthlyAmountLarger[14] = double(monthlyAvg[0]); + avgMonthlyAmountLarger[15] = double(monthlyAvg[1]); + + for (int iDay=0; iDay<365; iDay++) + { + outputDailyValues[iDay] = float(interpolation::cubicSpline(iDay, monthMid, avgMonthlyAmountLarger, 16)); + } + // leap years + outputDailyValues[365] = outputDailyValues[0]; + + delete [] avgMonthlyAmountLarger; + } + + + /*! + * \brief Computes daily values starting from monthly mean + * using quadratic spline + * original Campbell function + * it has a discontinuity between end and start of the year + */ + void quadrSplineYearInterpolate(float *meanY, float *dayVal) + { + float a[13] = {0}; + float b[14] = {0}; + float c[13] = {0}; + float aa[13] = {0}; + float bb[13] = {0}; + float cc[13] = {0}; + float d[14] = {0}; + float h[13] = {0}; + + int i,j; + + int monthLastDoy [13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; + + d[1] = meanY[0] - meanY[11]; + h[0] = 30; + + for (i = 1; i<=12; i++) + { + if (i == 12) + d[i + 1] = meanY[0] - meanY[i-1]; + else + d[i + 1] = meanY[i] - meanY[i-1]; + + h[i] = float(monthLastDoy[i] - monthLastDoy[i - 1] - 1); + aa[i] = h[i - 1] / 6; + bb[i] = (h[i - 1] + h[i]) / 3; + cc[i] = h[i] / 6; + } + + for (i = 1; i<= 11; i++) + { + cc[i] = cc[i] / bb[i]; + d[i] = d[i] / bb[i]; + bb[i + 1] = bb[i + 1] - aa[i + 1] * cc[i]; + d[i + 1] = d[i + 1] - aa[i + 1] * d[i]; + } + + b[12] = d[12] / bb[12]; + for (i = 11; i>=1; i--) + b[i] = d[i] - cc[i] * b[i + 1]; + + for (i = 1; i<=12; i++) + { + a[i] = (b[i + 1] - b[i]) / (2 * h[i]); + c[i] = meanY[i-1] - (b[i + 1] + 2 * b[i]) * h[i] / 6; + } + + j = 0; + for (i = 1; i<=365; i++) + { + if (monthLastDoy[j] < i) + j = j + 1; + int t = i - monthLastDoy[j - 1] - 1; + + dayVal[i-1] = c[j] + b[j] * t + a[j] * t * t; + + } + + dayVal[365] = dayVal[0]; + } + + double cubicSpline(double x, double *firstColumn, double *secondColumn, int dim) { double a,b,c,d,y; diff --git a/mathFunctions/furtherMathFunctions.h b/mathFunctions/furtherMathFunctions.h index fe995622..09656dfd 100644 --- a/mathFunctions/furtherMathFunctions.h +++ b/mathFunctions/furtherMathFunctions.h @@ -93,7 +93,10 @@ enum estimatedFunction {FUNCTION_CODE_SPHERICAL, FUNCTION_CODE_LINEAR, FUNCTION_ double normGeneric(int idFunction, double *parameters, int nrParameters, double *x, double *y, int nrData); double modifiedVanGenuchten(double psi, double *parameters, bool isRestricted); - double cubicSpline(double x , double *firstColumn , double *secondColumn, int dim); // not working to be checked + double cubicSpline(double x , double *firstColumn , double *secondColumn, int dim); + void cubicSplineYearInterpolate(float *monthlyAvg, float *outputDailyValues); + void quadrSplineYearInterpolate(float *meanY, float *dayVal); + bool punctualSecondDerivative(int dim, double *firstColumn , double *secondColumn, double* secondDerivative); // not working to be checked void tridiagonalThomasAlgorithm (int n, double *subDiagonal, double *mainDiagonal, double *superDiagonal, double *constantTerm, double* output); // not working to be checked diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index a31cc376..a845627f 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -1,6 +1,7 @@ #include "waterTable.h" #include "commonConstants.h" -#include "weatherGenerator.h" +#include "furtherMathFunctions.h" + WaterTable::WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings) @@ -180,7 +181,7 @@ bool WaterTable::computeWTClimate() WTClimateMonthly[myMonthIndex] = H_sum[myMonthIndex] / H_num[myMonthIndex]; } isClimateReady = true; - cubicSplineYearInterpolate(WTClimateMonthly, WTClimateDaily); + interpolation::cubicSplineYearInterpolate(WTClimateMonthly, WTClimateDaily); return true; } diff --git a/waterTable/waterTable.pro b/waterTable/waterTable.pro index c012e2a1..55a69b5a 100644 --- a/waterTable/waterTable.pro +++ b/waterTable/waterTable.pro @@ -24,7 +24,7 @@ win32:{ TARGET = waterTable } -INCLUDEPATH += ../crit3dDate ../mathFunctions ../meteo ../interpolation ../gis ../commonChartElements ../weatherGenerator +INCLUDEPATH += ../crit3dDate ../mathFunctions ../meteo ../interpolation ../gis ../commonChartElements SOURCES += \ dialogSelectWell.cpp \ diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 65b49352..cd07d7a2 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -231,14 +231,14 @@ void initializeWeather(TweatherGenClimate &wGen) mMeanPrecip[m] = mMeanPrecip[m] / (fWetDays[m] * float(daysInMonth)); } - cubicSplineYearInterpolate(mpww, wGen.daily.pww); - cubicSplineYearInterpolate(mpwd, wGen.daily.pwd); - cubicSplineYearInterpolate(mMeanDryTMax, wGen.daily.meanDryTMax); - cubicSplineYearInterpolate(mMeanPrecip, wGen.daily.meanPrecip); - cubicSplineYearInterpolate(mMeanWetTMax, wGen.daily.meanWetTMax); - cubicSplineYearInterpolate(mMeanTMin, wGen.daily.meanTMin); - cubicSplineYearInterpolate(mMinTempStd, wGen.daily.minTempStd); - cubicSplineYearInterpolate(mMaxTempStd, wGen.daily.maxTempStd); + interpolation::cubicSplineYearInterpolate(mpww, wGen.daily.pww); + interpolation::cubicSplineYearInterpolate(mpwd, wGen.daily.pwd); + interpolation::cubicSplineYearInterpolate(mMeanDryTMax, wGen.daily.meanDryTMax); + interpolation::cubicSplineYearInterpolate(mMeanPrecip, wGen.daily.meanPrecip); + interpolation::cubicSplineYearInterpolate(mMeanWetTMax, wGen.daily.meanWetTMax); + interpolation::cubicSplineYearInterpolate(mMeanTMin, wGen.daily.meanTMin); + interpolation::cubicSplineYearInterpolate(mMinTempStd, wGen.daily.minTempStd); + interpolation::cubicSplineYearInterpolate(mMaxTempStd, wGen.daily.maxTempStd); } @@ -315,114 +315,6 @@ float weibull (float dailyAvgPrec, float precThreshold) } - -/*! - * \brief Computes daily values starting from monthly averages using cubic spline - * \param monthlyAvg: vector of monthly averages (12 values) - * outputDailyValues: vector of interpolated daily values (366 values) -*/ -void cubicSplineYearInterpolate(float *monthlyAvg, float *outputDailyValues) -{ - double monthMid [16] = {-61, - 31, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396}; - - for (int iMonth=0; iMonth<16; iMonth++) - { - monthMid[iMonth] += 15; - } - - double* avgMonthlyAmountLarger = new double[16]; - for (int iMonth = 0; iMonth < 12; iMonth++) - { - avgMonthlyAmountLarger[iMonth+2] = double(monthlyAvg[iMonth]); - } - - avgMonthlyAmountLarger[0] = double(monthlyAvg[10]); - avgMonthlyAmountLarger[1] = double(monthlyAvg[11]); - avgMonthlyAmountLarger[14] = double(monthlyAvg[0]); - avgMonthlyAmountLarger[15] = double(monthlyAvg[1]); - - for (int iDay=0; iDay<365; iDay++) - { - outputDailyValues[iDay] = interpolation::cubicSpline(iDay, monthMid, avgMonthlyAmountLarger, 16); - } - // leap years - outputDailyValues[365] = outputDailyValues[0]; - - delete [] avgMonthlyAmountLarger; -} - - -/*! - * \brief Computes daily values starting from monthly mean - * using quadratic spline - * original Campbell function - * it has a discontinuity between end and start of the year -*/ -void quadrSplineYearInterpolate(float *meanY, float *dayVal) -{ - float a[13] = {0}; - float b[14] = {0}; - float c[13] = {0}; - float aa[13] = {0}; - float bb[13] = {0}; - float cc[13] = {0}; - float d[14] = {0}; - float h[13] = {0}; - float t = 0; - - int i,j; - - int monthends [13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; - - d[1] = meanY[0] - meanY[11]; - h[0] = 30; - - for (i = 1; i<=12; i++) - { - if (i == 12) - d[i + 1] = meanY[0] - meanY[i-1]; - else - d[i + 1] = meanY[i] - meanY[i-1]; - - h[i] = monthends[i] - monthends[i - 1] - 1; - aa[i] = h[i - 1] / 6; - bb[i] = (h[i - 1] + h[i]) / 3; - cc[i] = h[i] / 6; - } - - for (i = 1; i<= 11; i++) - { - cc[i] = cc[i] / bb[i]; - d[i] = d[i] / bb[i]; - bb[i + 1] = bb[i + 1] - aa[i + 1] * cc[i]; - d[i + 1] = d[i + 1] - aa[i + 1] * d[i]; - } - - b[12] = d[12] / bb[12]; - for (i = 11; i>=1; i--) - b[i] = d[i] - cc[i] * b[i + 1]; - - for (i = 1; i<=12; i++) - { - a[i] = (b[i + 1] - b[i]) / (2 * h[i]); - c[i] = meanY[i-1] - (b[i + 1] + 2 * b[i]) * h[i] / 6; - } - - j = 0; - for (i = 1; i<=365; i++) - { - if (monthends[j] < i) - j = j + 1; - t = i - monthends[j - 1] - 1; - - dayVal[i-1] = c[j] + b[j] * t + a[j] * t * t; - - } - - dayVal[365] = dayVal[0]; -} - - /*! * \brief generates maximum and minimum temperature */ diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index fde0b9b6..8ee55148 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -92,8 +92,6 @@ bool markov(float pwd, float pww, bool isWetPreviousDay); float weibull (float mean, float precThreshold); - void cubicSplineYearInterpolate(float *monthlyAvg, float *outputDailyValues); - void quadrSplineYearInterpolate(float *meanY, float *dayVal); void genTemps(float *tMax, float *tMin, float meanTMax, float meanTMin, float stdMax, float stdMin, float *resTMaxPrev, float *resTMinPrev); From 1873641447c601a4c70f0a0b038fcef5877f3d7f Mon Sep 17 00:00:00 2001 From: cate-to Date: Fri, 31 May 2024 15:20:51 +0200 Subject: [PATCH 023/179] fixed bug and changed multiple detrending --- interpolation/interpolation.cpp | 141 ++++++++++++++++--------- interpolation/interpolationConstants.h | 10 +- project/dialogInterpolation.cpp | 3 +- project/project.cpp | 54 ---------- proxyWidget/localProxyWidget.cpp | 37 +------ 5 files changed, 98 insertions(+), 147 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index cd02bf38..623928b1 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1362,41 +1362,53 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati double min = mySettings->getMinMaxTemperature()[0]; double max = mySettings->getMinMaxTemperature()[1]; std::vector tempParam; - if (mySettings->getChosenElevationFunction() == frei) - { - mySettings->getProxy(i)->setFittingFunctionName(frei); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {min, 0, -4, -200, 0.1, max+10, 0.006, 4, 1800, 1000}; - } - else if (mySettings->getChosenElevationFunction() == piecewiseTwo) + if (mySettings->getChosenElevationFunction() == piecewiseTwo) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) + if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 0, -0.006, 1800, max+2, 0.01, 0}; - } - else if (mySettings->getChosenElevationFunction() == piecewiseThree) - { - mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 100, 0, -0.006, 1800, max+2, 1000, (max-min-2), 0}; + else + { + tempParam = mySettings->getProxy(i)->getFittingParametersRange(); + tempParam[1] = min-2; + tempParam[5] = max+2; + } } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) + if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 100, 0.001, -0.006, -0.006, 1800, max+2, 1000, 0.007, 0, 0}; + else + { + tempParam = mySettings->getProxy(i)->getFittingParametersRange(); + tempParam[1] = min-2; + tempParam[7] = max+2; + } } - else if (mySettings->getChosenElevationFunction() == piecewiseThreeSlope) + else if (mySettings->getChosenElevationFunction() == piecewiseThree) { - mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeSlope); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) + mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); + if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 100, 0.001, -0.006, 1800, max+2, 1000, 0.007, 0}; + else + { + tempParam = mySettings->getProxy(i)->getFittingParametersRange(); + tempParam[1] = min-2; + tempParam[6] = max+2; + } } else if (mySettings->getChosenElevationFunction() == freiFree) { mySettings->getProxy(i)->setFittingFunctionName(freiFree); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) + if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 1800, 1000, 0.006}; + else + { + tempParam = mySettings->getProxy(i)->getFittingParametersRange(); + tempParam[0] = min-2; + tempParam[6] = max+10; + } } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } @@ -1413,12 +1425,18 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 std::string &errorStr) { bool isPreviousParam = false; + unsigned int elevationPos = NODATA; + + for (unsigned int i = 0; i < mySettings->getSelectedCombination().getProxySize(); i++) + { + if (getProxyPragaName(mySettings->getProxy(i)->getName()) == proxyHeight) + elevationPos = i; + } if (myCombination.getProxySize() > 0) { - if (myCombination.isProxyActive(0)) //siamo nel caso elevation + if (myCombination.isProxyActive(elevationPos)) { - //controlla se ci sono parametri salvati per l'elevation if (paramFirstGuess.size() > 0) { if (paramFirstGuess[0].size() > 0) @@ -1431,6 +1449,7 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 isPreviousParam = true; } } + else return false; const double RATIO_DELTA = 1000; @@ -1443,7 +1462,7 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 myFunc.push_back(lapseRatePiecewise_two); else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) myFunc.push_back(lapseRatePiecewiseFree); - else if (mySettings->getChosenElevationFunction() == piecewiseThreeSlope) + else if (mySettings->getChosenElevationFunction() == piecewiseThree) myFunc.push_back(lapseRatePiecewiseThree_withSlope); else if (mySettings->getChosenElevationFunction() == freiFree) myFunc.push_back(lapseRateFreiFree); @@ -1522,10 +1541,10 @@ bool setAllFittingParameters(Crit3DProxyCombination myCombination, Crit3DInterpo if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 100, 0.001, -0.006, -0.006, 1800, max+2, 1000, 0.01, 0, 0}; } - else if (mySettings->getChosenElevationFunction() == piecewiseThreeSlope) + else if (mySettings->getChosenElevationFunction() == piecewiseThree) { myFunc.push_back(lapseRatePiecewiseThree_withSlope); - mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeSlope); + mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 100, 0.002, -0.006, 1800, max+2, 1000, 0.01, 0}; } @@ -1614,15 +1633,22 @@ bool multipleDetrendingMain(std::vector &myPoints std::vector > elevationParameters = mySettings->getFittingParameters(); size_t paramSize = mySettings->getFittingParameters().size(); mySettings->clearFitting(); + int elevationPos = NODATA; + + for (unsigned int pos=0; pos < mySettings->getCurrentCombination().getProxySize(); pos++) + { + if (getProxyPragaName(mySettings->getProxy(pos)->getName()) == proxyHeight) + elevationPos = pos; + } - if (mySettings->getCurrentCombination().isProxyActive(0)) + if (mySettings->getCurrentCombination().isProxyActive(elevationPos)) { if (elevationParameters.size() > 0) //forse meglio fare vettore con dimensione = nrProxy (attivi) { - while (elevationParameters.back().size() < 5) + while (elevationParameters.back().size() < 4) elevationParameters.pop_back(); - if (otherParameters[1].size() > 2) + if (otherParameters[0].size() > 2) { for (int i = 0; i < (paramSize - 1); i++) otherParameters[i] = otherParameters[i+1]; @@ -1632,14 +1658,14 @@ bool multipleDetrendingMain(std::vector &myPoints Crit3DProxyCombination elevationCombination; elevationCombination.resetCombination(mySettings->getSelectedCombination().getProxySize()); - elevationCombination.setProxyActive(0, true); + elevationCombination.setProxyActive(elevationPos, true); if (!multipleDetrendingElevation(elevationCombination, elevationParameters, myPoints, mySettings, myVar, errorStr)) return true; } Crit3DProxyCombination othersCombination = mySettings->getSelectedCombination(); - othersCombination.setProxyActive(0,false); + othersCombination.setProxyActive(elevationPos,false); if (!multipleDetrending(othersCombination, otherParameters, myPoints, mySettings, myVar, errorStr)) return true; @@ -1653,30 +1679,40 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st { if (! getUseDetrendingVar(myVar)) return true; - int pos = 0; - Crit3DProxy* elevationProxy = mySettings->getProxy(pos); + int elevationPos = NODATA; + + for (unsigned int pos = 0; pos < elevationCombination.getProxySize(); pos++) + { + if (elevationCombination.isProxyActive(pos)) + elevationPos = pos; + } + + if (elevationPos == NODATA) + return true; + + Crit3DProxy* elevationProxy = mySettings->getProxy(elevationPos); // proxy spatial variability (1st step) double avg, stdDev; unsigned validNr; validNr = 0; - if (proxyValidity(myPoints, pos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + if (proxyValidity(myPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) { - elevationCombination.setProxySignificant(pos, true); + elevationCombination.setProxySignificant(elevationPos, true); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); - myCombination.setProxySignificant(pos, true); + myCombination.setProxySignificant(elevationPos, true); mySettings->setCurrentCombination(myCombination); elevationProxy->setIsSignificant(true); } else { - elevationCombination.setProxySignificant(pos, false); + elevationCombination.setProxySignificant(elevationPos, false); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); - myCombination.setProxyActive(pos, false); - myCombination.setProxySignificant(pos, false); + myCombination.setProxyActive(elevationPos, false); + myCombination.setProxySignificant(elevationPos, false); mySettings->setCurrentCombination(myCombination); - mySettings->getProxy(pos)->setIsSignificant(false); + mySettings->getProxy(elevationPos)->setIsSignificant(false); return true; } @@ -1691,7 +1727,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st isValid = true; if (elevationProxy->getIsSignificant()) { - proxyValue = it->getProxyValue(pos); + proxyValue = it->getProxyValue(elevationPos); if (proxyValue == NODATA) { isValid = false; @@ -1706,20 +1742,20 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st } // proxy spatial variability (2nd step) - if (proxyValidity(myPoints, pos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + if (proxyValidity(myPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) { - elevationCombination.setProxySignificant(pos, true); + elevationCombination.setProxySignificant(elevationPos, true); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); - myCombination.setProxySignificant(pos, true); + myCombination.setProxySignificant(elevationPos, true); mySettings->setCurrentCombination(myCombination); elevationProxy->setIsSignificant(true); } else { - elevationCombination.setProxySignificant(pos, false); + elevationCombination.setProxySignificant(elevationPos, false); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); - myCombination.setProxyActive(pos, false); - myCombination.setProxySignificant(pos, false); + myCombination.setProxyActive(elevationPos, false); + myCombination.setProxySignificant(elevationPos, false); mySettings->setCurrentCombination(myCombination); elevationProxy->setIsSignificant(false); return true; @@ -1732,7 +1768,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st for (i=0; i < myPoints.size(); i++) { - predictors.push_back(myPoints[i].getProxyValue(pos)); + predictors.push_back(myPoints[i].getProxyValue(elevationPos)); predictands.push_back(myPoints[i].value); weights.push_back(myPoints[i].regressionWeight); } @@ -1741,8 +1777,8 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st { elevationProxy->setIsSignificant(false); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); - myCombination.setProxyActive(pos, false); - myCombination.setProxySignificant(pos, false); + myCombination.setProxyActive(elevationPos, false); + myCombination.setProxySignificant(elevationPos, false); mySettings->setCurrentCombination(myCombination); return true; } @@ -1762,7 +1798,8 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st { return false; } - + int pos = 0; + auto func = myFunc[pos].target&)>(); if (!func) @@ -1776,7 +1813,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st 100, 0.005, 0.002, predictors, predictands, weights); mySettings->setFittingFunction(myFunc); - mySettings->setFittingParametersElevation(parameters[pos]); + mySettings->setFittingParametersElevation(parameters[elevationPos]); // detrending @@ -1784,9 +1821,9 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st for (i = 0; i < myPoints.size(); i++) { if ((elevationProxy->getIsSignificant())) - proxyValue = myPoints[i].getProxyValue(pos); + proxyValue = myPoints[i].getProxyValue(elevationPos); - detrendValue = float((*func)(proxyValue, parameters[pos])); + detrendValue = float((*func)(proxyValue, parameters[elevationPos])); myPoints[i].value -= detrendValue; } diff --git a/interpolation/interpolationConstants.h b/interpolation/interpolationConstants.h index 9eda20ae..4e368821 100644 --- a/interpolation/interpolationConstants.h +++ b/interpolation/interpolationConstants.h @@ -37,13 +37,13 @@ { "water_index", proxyWaterIndex} }; - enum TFittingFunction { piecewiseTwo, piecewiseThree, piecewiseThreeFree, piecewiseThreeSlope, frei, freiFree, linear, noFunction }; + enum TFittingFunction { piecewiseTwo, piecewiseThreeFree, piecewiseThree, freiFree, linear, noFunction }; const std::map fittingFunctionNames = { - { "Double piecewise", piecewiseTwo }, - { "Triple piecewise (6 parameters)", piecewiseThreeFree}, - { "Triple piecewise (5 parameters)", piecewiseThreeSlope}, - { "Nonlinear Frei function (5 parameters)", frei }, + { "piecewise_two", piecewiseTwo }, + { "free_triple_piecewise", piecewiseThreeFree}, + { "triple_piecewise", piecewiseThree}, + { "Nonlinear Frei function (6 parameters)", freiFree }, { "linear", linear } }; diff --git a/project/dialogInterpolation.cpp b/project/dialogInterpolation.cpp index 83ebe6fd..542e80c1 100644 --- a/project/dialogInterpolation.cpp +++ b/project/dialogInterpolation.cpp @@ -142,11 +142,10 @@ DialogInterpolation::DialogInterpolation(Project *myProject) std::map::const_iterator itElFunc; for (itElFunc = fittingFunctionNames.begin(); itElFunc != fittingFunctionNames.end(); ++itElFunc) { - if (itElFunc->first == "linear" || itElFunc->first == "Nonlinear Frei function (5 parameters)") + if (itElFunc->first == "linear" || itElFunc->first == "Nonlinear Frei function (6 parameters)") continue; elevationFunctionEdit.addItem(QString::fromStdString(itElFunc->first), QString::fromStdString(itElFunc->first)); } - QString elevationFunctionString = QString::fromStdString(getKeyStringElevationFunction(_interpolationSettings->getChosenElevationFunction())); int indexElFunction = elevationFunctionEdit.findData(elevationFunctionString); if (indexElFunction != -1) diff --git a/project/project.cpp b/project/project.cpp index c1b289bc..565f2699 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -706,61 +706,7 @@ bool Project::loadParameters(QString parametersFileName) myProxy->setFittingParametersRange(StringListToDouble(myList)); } - /*if (getProxyPragaName(name_.toStdString()) == proxyHeight) - { - if (parameters->contains("fitting_function")) - { - std::string elevationFuction = parameters->value("fitting_function").toString().toStdString(); - if (fittingFunctionNames.find(elevationFuction) == fittingFunctionNames.end()) - { - errorString = "Unknown function for elevation. Choose between: piecewiseTwo, piecewiseThreeSlope, piecewiseThreeFree."; - return false; - } - else - interpolationSettings.setChosenElevationFunction(fittingFunctionNames.at(elevationFuction)); - - if (parameters->contains("fitting_parameters")) - { - unsigned int nrParameters; - - if (interpolationSettings.getChosenElevationFunction()== piecewiseTwo) - nrParameters = 4; - else if (interpolationSettings.getChosenElevationFunction()== piecewiseThreeSlope) - nrParameters = 5; - else if (interpolationSettings.getChosenElevationFunction()== piecewiseThreeFree) - nrParameters = 6; - - myList = parameters->value("fitting_parameters").toStringList(); - if (myList.size() != nrParameters*2) - { - errorString = "Wrong number of fitting parameters for proxy: " + name_; - return false; - } - - myProxy->setFittingParametersRange(StringListToDouble(myList)); - } - } - else - { - interpolationSettings.setChosenElevationFunction(piecewiseTwo); - } - } - else - { - if(parameters->contains("fitting_parameters")) - { - unsigned int nrParameters = 1; - - myList = parameters->value("fitting_parameters").toStringList(); - if (myList.size() != nrParameters*2) - { - errorString = "Wrong number of fitting parameters for proxy: " + name_; - return false; - } - myProxy->setFittingParametersRange(StringListToDouble(myList)); - } - }*/ if (! parameters->contains("active")) { diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 6ac50693..a1548980 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -140,25 +140,7 @@ Crit3DLocalProxyWidget::Crit3DLocalProxyWidget(double x, double y, std::vectoraddStretch(30); selectionLayout->addLayout(selectionOptionLayout); - if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == frei && parameters[proxyPos].size() == 5) - { - QVBoxLayout *parametriLayout = new QVBoxLayout(); - - QLabel *freiT0Lab = new QLabel(QString("T0: %1").arg(parameters[proxyPos][0])); - QLabel *freiGammaLab = new QLabel(QString("Gamma: %1").arg(parameters[proxyPos][1])); - QLabel *freiALab = new QLabel(QString("a: %1").arg(parameters[proxyPos][2])); - QLabel *freiH0Lab = new QLabel(QString("H0: %1").arg(parameters[proxyPos][3])); - QLabel *freiH1Lab = new QLabel(QString("H1: %1").arg(parameters[proxyPos][4]+parameters[proxyPos][3])); - - parametriLayout->addWidget(freiT0Lab); - parametriLayout->addWidget(freiGammaLab); - parametriLayout->addWidget(freiALab); - parametriLayout->addWidget(freiH0Lab); - parametriLayout->addWidget(freiH1Lab); - - selectionLayout->addLayout(parametriLayout); - } - else if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree && parameters[proxyPos].size() == 5) + if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree && parameters[proxyPos].size() == 5) { QVBoxLayout *parametriLayout = new QVBoxLayout(); @@ -213,7 +195,7 @@ Crit3DLocalProxyWidget::Crit3DLocalProxyWidget(double x, double y, std::vectoraddLayout(parametriLayout); } - else if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeSlope && parameters[proxyPos].size() == 5) + else if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree && parameters[proxyPos].size() == 5) { QVBoxLayout *parametriLayout = new QVBoxLayout(); @@ -606,20 +588,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) point.setY(myY); point_vector.append(point); } - else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == frei) - { - std::vector xVector; - for (int m = xMin; m < xMax; m += 5) - xVector.push_back(m); - - for (int p = 0; p < xVector.size(); p++) - { - point.setX(xVector[p]); - point.setY(lapseRateFrei(xVector[p], parameters[proxyPos])); - point_vector.append(point); - } - } - else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeSlope) + else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree) { std::vector xVector; for (int m = xMin; m < xMax; m += 5) From 074020132cea3e615d327e663f40285d309476fa Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 31 May 2024 15:24:34 +0200 Subject: [PATCH 024/179] update wg --- waterTable/waterTable.cpp | 4 +- weatherGenerator/weatherGenerator.cpp | 56 ++++++++++++++++----------- weatherGenerator/weatherGenerator.h | 11 +++--- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index a845627f..101ab4b9 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -483,7 +483,9 @@ bool WaterTable::computeWaterTableClimate(QDate currentDate, int yearFrom, int y } } -// restituisce il dato interpolato considerando i dati osservati + +// restituisce il dato interpolato di profonditร  considerando i dati osservati +// nella stessa unitร  di misura degli osservati (default: cm) bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays) { *myValue = NODATA; diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index cd07d7a2..76a9d2f2 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -162,7 +162,7 @@ void initializeDailyDataBasic(ToutputDailyMeteo* dailyData, Crit3DDate myDate) dailyData->maxTemp = NODATA; dailyData->minTemp = NODATA; dailyData->prec = NODATA; - + dailyData->waterTableDepth = NODATA; } @@ -638,7 +638,7 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int * Output is written on outputFileName (csv) */ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, - TweatherGenClimate& wGenClimate, TinputObsData* lastYearDailyObsData, + TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, float rainfallThreshold) { @@ -657,8 +657,8 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno // it checks if observed data includes the last 9 months before wgDoy1 int nrDaysBeforeWgDoy1; - if (! checkLastYearDate(lastYearDailyObsData->inputFirstDate, lastYearDailyObsData->inputLastDate, - lastYearDailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) + if (! checkLastYearDate(dailyObsData->inputFirstDate, dailyObsData->inputLastDate, + dailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) { qDebug() << "ERROR: observed data should include at least 9 months before wgDoy1"; return false; @@ -710,10 +710,12 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) { dailyPredictions[tmp].date = myDate; - obsIndex = difference(lastYearDailyObsData->inputFirstDate, dailyPredictions[tmp].date); - dailyPredictions[tmp].minTemp = lastYearDailyObsData->inputTMin[obsIndex]; - dailyPredictions[tmp].maxTemp = lastYearDailyObsData->inputTMax[obsIndex]; - dailyPredictions[tmp].prec = lastYearDailyObsData->inputPrecip[obsIndex]; + obsIndex = difference(dailyObsData->inputFirstDate, dailyPredictions[tmp].date); + dailyPredictions[tmp].minTemp = dailyObsData->inputTMin[obsIndex]; + dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; + dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; + //dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() + // in base a wgdoy1 e wgdoy2 aggiungi giorni (vuoti) a watertable if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) @@ -772,7 +774,7 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno isLastMember = true; } // compute seasonal prediction - if (!computeSeasonalPredictions(lastYearDailyObsData, wGen, + if (! computeSeasonalPredictions(dailyObsData, wGen, myPredictionYear, myYear, nrRepetitions, wgDoy1, wgDoy2, rainfallThreshold, isLastMember, dailyPredictions, &outputDataLength )) @@ -781,6 +783,14 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno return false; } + /* TODO + for (int tmp = wgDoy1; tmp < wgDoy2; tmp++) + { + // passi a watertable i valori tmin tmax prec da wgdoy1 a wgdoy2 + // calcola etp + // dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() + }*/ + // next model myYear = myYear + nrRepetitions; } @@ -802,10 +812,10 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno Period between wgDoy1 and wgDoy2 is produced by the WG Others data are a copy of the observed data of predictionYear Weather generator climate is stored in wgClimate - Observed data (Tmin, Tmax, Prec) are in lastYearDailyObsData + Observed data (Tmin, Tmax, Prec) are in dailyObsData \return outputDailyData */ -bool computeSeasonalPredictions(TinputObsData *lastYearDailyObsData, TweatherGenClimate &wgClimate, +bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate &wgClimate, int predictionYear, int firstYear, int nrRepetitions, int wgDoy1, int wgDoy2, float rainfallThreshold, bool isLastMember, std::vector& outputDailyData, int *outputDataLength) @@ -899,13 +909,13 @@ bool computeSeasonalPredictions(TinputObsData *lastYearDailyObsData, TweatherGen else if (myDoy > fixWgDoy2) obsDate.year = predictionYear-1; - obsIndex = difference(lastYearDailyObsData->inputFirstDate, obsDate); + obsIndex = difference(dailyObsData->inputFirstDate, obsDate); - if ( obsIndex >= 0 && obsIndex <= lastYearDailyObsData->dataLength ) + if ( obsIndex >= 0 && obsIndex <= dailyObsData->dataLength ) { - outputDailyData[currentIndex].maxTemp = lastYearDailyObsData->inputTMax[obsIndex]; - outputDailyData[currentIndex].minTemp = lastYearDailyObsData->inputTMin[obsIndex]; - outputDailyData[currentIndex].prec = lastYearDailyObsData->inputPrecip[obsIndex]; + outputDailyData[currentIndex].maxTemp = dailyObsData->inputTMax[obsIndex]; + outputDailyData[currentIndex].minTemp = dailyObsData->inputTMin[obsIndex]; + outputDailyData[currentIndex].prec = dailyObsData->inputPrecip[obsIndex]; } else { @@ -980,8 +990,8 @@ bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly *XM /* // it checks if observed data includes the last 9 months before wgDoy1 int nrDaysBeforeWgDoy1; - if (! checkLastYearDate(lastYearDailyObsData->inputFirstDate, lastYearDailyObsData->inputLastDate, - lastYearDailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) + if (! checkLastYearDate(dailyObsData->inputFirstDate, dailyObsData->inputLastDate, + dailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) { qDebug() << "ERROR: observed data should include at least 9 months before wgDoy1"; return false; @@ -1033,10 +1043,10 @@ bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly *XM for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) { dailyPredictions[tmp].date = myDate; - obsIndex = difference(lastYearDailyObsData->inputFirstDate, dailyPredictions[tmp].date); - dailyPredictions[tmp].minTemp = lastYearDailyObsData->inputTMin[obsIndex]; - dailyPredictions[tmp].maxTemp = lastYearDailyObsData->inputTMax[obsIndex]; - dailyPredictions[tmp].prec = lastYearDailyObsData->inputPrecip[obsIndex]; + obsIndex = difference(dailyObsData->inputFirstDate, dailyPredictions[tmp].date); + dailyPredictions[tmp].minTemp = dailyObsData->inputTMin[obsIndex]; + dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; + dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) @@ -1095,7 +1105,7 @@ bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly *XM isLastMember = true; } // compute seasonal prediction - if (!computeSeasonalPredictions(lastYearDailyObsData, wGen, + if (!computeSeasonalPredictions(dailyObsData, wGen, myPredictionYear, myYear, nrRepetitions, wgDoy1, wgDoy2, rainfallThreshold, isLastMember, dailyPredictions, &outputDataLength )) diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index 8ee55148..2579f74c 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -72,9 +72,10 @@ struct ToutputDailyMeteo { Crit3DDate date; - float minTemp; - float maxTemp; - float prec; + float minTemp; // [C] + float maxTemp; // [C] + float prec; // [mm] + float waterTableDepth; // [m] }; void initializeDailyDataBasic(ToutputDailyMeteo* dailyData, Crit3DDate myDate); @@ -110,10 +111,10 @@ TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen); bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, - TweatherGenClimate& wGenClimate, TinputObsData* lastYearDailyObsData, + TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, int numRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, float rainfallThreshold); - bool computeSeasonalPredictions(TinputObsData *lastYearDailyObsData, TweatherGenClimate& wgClimate, + bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate& wgClimate, int predictionYear, int firstYear, int nrRepetitions, int wgDoy1, int wgDoy2, float minPrec, bool isLastMember, std::vector &outputDailyData, int *outputDataLength); From b753a2b24980beb068caa9143a30e1f17db6589c Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Fri, 31 May 2024 15:28:20 +0200 Subject: [PATCH 025/179] weather generator anomaly e produzione output da debuggare --- weatherGenerator/weatherGenerator.cpp | 182 +++----------------------- weatherGenerator/weatherGenerator.h | 5 - 2 files changed, 16 insertions(+), 171 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 65b49352..5da6b18a 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -664,7 +664,7 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int anomalyMonth1, int anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) { - unsigned int i = 0; + //unsigned int i = 0; QString myVar; float myValue = 0.0; @@ -673,20 +673,20 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int // loop for all XMLValuesList (Tmin, Tmax, TminVar, TmaxVar, Prec3M, Wetdays) for (int iSeason=0;iSeason<4;iSeason++) { - for (i = 0; i < 4; i++) + for (unsigned int iWeatherVariable = 0; iWeatherVariable < 4; iWeatherVariable++) { - if (XMLAnomaly->period[iSeason].seasonalScenarios[i].attribute.toUpper() == "ANOMALY") + if (XMLAnomaly->period[iSeason].seasonalScenarios[iWeatherVariable].attribute.toUpper() == "ANOMALY") { - myVar = XMLAnomaly->period[iSeason].seasonalScenarios[i].type.toUpper(); + myVar = XMLAnomaly->period[iSeason].seasonalScenarios[iWeatherVariable].type.toUpper(); result = false; //if (XMLAnomaly->forecast[i].value[modelIndex] != nullptr) - myValue = XMLAnomaly->period[iSeason].seasonalScenarios[i].value[modelIndex].toFloat(); + myValue = XMLAnomaly->period[iSeason].seasonalScenarios[iWeatherVariable].value[modelIndex].toFloat(); //else //myValue = NODATA; if (int(myValue) != int(NODATA)) { - /*if ( (myVar == "TMIN") || (myVar == "AVGTMIN") ) + if ( (myVar == "TMIN") || (myVar == "AVGTMIN") ) result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmin, wGen.monthly.monthlyTmin); else if ( (myVar == "TMAX") || (myVar == "AVGTMAX") ) result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmax, wGen.monthly.monthlyTmax); @@ -698,9 +698,11 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.probabilityWetWet, wGen.monthly.probabilityWetWet); else if ( (myVar == "DELTATMAXDRYWET") ) result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.dw_Tmax, wGen.monthly.dw_Tmax); -*/ + } - /*else + + + else { // not critical variables if ((myVar == "DELTATMAXDRYWET") || (myVar == "WETWETDAYSFREQUENCY")) @@ -711,9 +713,14 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int { qDebug() << "wrong anomaly: " + myVar; return false; - }*/ + } } } + // move to the next season + anomalyMonth1 = (anomalyMonth1 + 3)%12; + if (anomalyMonth1 == 0) anomalyMonth1 +=12; + anomalyMonth2 = (anomalyMonth2 + 3)%12; + if (anomalyMonth2 == 0) anomalyMonth2 +=12; } /* DEBUG QString anomaly="anomaly.txt"; @@ -1068,160 +1075,3 @@ bool computeClimate(TweatherGenClimate &wgClimate, int firstYear, int nrRepetiti return true; } -bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly *XMLAnomaly, - TweatherGenClimate& wGenClimate, - int nrRepetitions, int myPredictionYear, int *wgDoy1, int *wgDoy2, - float rainfallThreshold) -{ - TweatherGenClimate wGen; - std::vector dailyPredictions; - - Crit3DDate myFirstDatePrediction, seasonFirstDate, seasonLastDate; - - unsigned int nrMembers; // number of models into xml anomaly file - unsigned int nrYears; // number of years of the output series. It is the length of the virtual period where all the previsions (one for each model) are given one after another - unsigned int nrValues; // number of days between the first and the last prediction year - int firstYear, lastYear, myYear; - unsigned int obsIndex; - unsigned int addday = 0; - bool isLastMember = false; - /* - // it checks if observed data includes the last 9 months before wgDoy1 - int nrDaysBeforeWgDoy1; - if (! checkLastYearDate(lastYearDailyObsData->inputFirstDate, lastYearDailyObsData->inputLastDate, - lastYearDailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) - { - qDebug() << "ERROR: observed data should include at least 9 months before wgDoy1"; - return false; - } - - nrMembers = 0; - for (int i = 0; imodelMember.size(); i++) - { - nrMembers += XMLAnomaly->modelMember[i].toUInt(); - } - */ - //nrYears = nrMembers * unsigned(nrRepetitions); - nrYears = nrRepetitions; - firstYear = myPredictionYear; - /* - // wgDoy1 within myPredictionYear, wgDoy2 within myPredictionYear+1 - if (wgDoy1 < wgDoy2) - lastYear = firstYear + signed(nrYears) - 1; - else - lastYear = firstYear + signed(nrYears); - - seasonFirstDate = getDateFromDoy (myPredictionYear, wgDoy1); - if (wgDoy1 < wgDoy2) - seasonLastDate = getDateFromDoy (myPredictionYear, wgDoy2); - else - seasonLastDate = getDateFromDoy (myPredictionYear+1, wgDoy2); - - myFirstDatePrediction = seasonFirstDate.addDays(-nrDaysBeforeWgDoy1); - - for (int i = myPredictionYear; i <= lastYear; i++) - { - if (isLeapYear(i)) - addday++; - } - - nrValues = nrYears * 365 + addday +1; - if (nrValues <= 0) - { - qDebug() << "ERROR: wrong date"; - return false; - } - - dailyPredictions.resize(nrValues); - - // copy the last 9 months before wgDoy1 - float lastTmax = NODATA; - float lastTmin = NODATA; - Crit3DDate myDate = myFirstDatePrediction; - for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) - { - dailyPredictions[tmp].date = myDate; - obsIndex = difference(lastYearDailyObsData->inputFirstDate, dailyPredictions[tmp].date); - dailyPredictions[tmp].minTemp = lastYearDailyObsData->inputTMin[obsIndex]; - dailyPredictions[tmp].maxTemp = lastYearDailyObsData->inputTMax[obsIndex]; - dailyPredictions[tmp].prec = lastYearDailyObsData->inputPrecip[obsIndex]; - - if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) - || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) - || (int(dailyPredictions[tmp].prec) == int(NODATA))) - { - if (tmp == 0) - { - qDebug() << "ERROR: Missing data:" << QString::fromStdString(dailyPredictions[tmp].date.toStdString()); - return false; - } - else - { - qDebug() << "WARNING: Missing data:" << QString::fromStdString(dailyPredictions[tmp].date.toStdString()); - - if (int(dailyPredictions[tmp].maxTemp) == int(NODATA)) - dailyPredictions[tmp].maxTemp = lastTmax; - - if (int(dailyPredictions[tmp].minTemp) == int(NODATA)) - dailyPredictions[tmp].minTemp = lastTmin; - - if (int(dailyPredictions[tmp].prec) == int(NODATA)) - dailyPredictions[tmp].prec = 0; - } - } - else - { - lastTmax = dailyPredictions[tmp].maxTemp; - lastTmin = dailyPredictions[tmp].minTemp; - } - ++myDate; - } - - qDebug() << "Observed OK"; - int outputDataLength = nrDaysBeforeWgDoy1; - - // store the climate without anomalies - wGen = wGenClimate; - myYear = firstYear; - - // first month of my season - int anomalyMonth1 = seasonFirstDate.month; - // last month of my season - int anomalyMonth2 = seasonLastDate.month; - - for (unsigned int modelIndex = 0; modelIndex < nrMembers; modelIndex++) - { - // assign anomaly - if ( !assignXMLAnomaly(XMLAnomaly, modelIndex, anomalyMonth1, anomalyMonth2, wGenClimate, wGen)) - { - qDebug() << "Error in Scenario: assignXMLAnomaly returns false"; - return false; - } - - if (modelIndex == nrMembers-1 ) - { - isLastMember = true; - } - // compute seasonal prediction - if (!computeSeasonalPredictions(lastYearDailyObsData, wGen, - myPredictionYear, myYear, nrRepetitions, - wgDoy1, wgDoy2, rainfallThreshold, isLastMember, - dailyPredictions, &outputDataLength )) - { - qDebug() << "Error in computeSeasonalPredictions"; - return false; - } - - // next model - myYear = myYear + nrRepetitions; - } - - qDebug() << "\n>>> output:" << outputFileName; - - writeMeteoDataCsv (outputFileName, separator, dailyPredictions); - - dailyPredictions.clear(); - */ - return true; -} - diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index fde0b9b6..68913c0f 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -125,11 +125,6 @@ void clearInputData(TinputObsData &myData); - bool makeScenario(QString outputFileName, char separator, XMLScenarioAnomaly* XMLAnomaly, - TweatherGenClimate& wGenClimate, - int nrRepetitions, int myPredictionYear, int* wgDoy1, int* wgDoy2, - float rainfallThreshold); - #endif // WEATHERGENERATOR_H From 28ab6b5301bf4af8a57f174f86edc32856701835 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Fri, 31 May 2024 15:44:49 +0200 Subject: [PATCH 026/179] check if lat lon exist or using default --- weatherGenerator/parserXML.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/weatherGenerator/parserXML.cpp b/weatherGenerator/parserXML.cpp index 2ad0912e..12846790 100644 --- a/weatherGenerator/parserXML.cpp +++ b/weatherGenerator/parserXML.cpp @@ -186,12 +186,22 @@ bool parseXMLSeasonal(const QString &xmlFileName, XMLSeasonalAnomaly &XMLAnomaly } else if ((myTag == "LAT") || (myTag == "LATITUDE")) { - XMLAnomaly.point.latitude = child.toElement().text().toFloat(); + bool ok; + XMLAnomaly.point.latitude = child.toElement().text().toFloat(&ok); + if (ok == false) + { + XMLAnomaly.point.latitude = NODATA; + } nrTokens++; } else if ((myTag == "LON") || (myTag == "LONGITUDE")) { - XMLAnomaly.point.longitude = child.toElement().text().toFloat(); + bool ok; + XMLAnomaly.point.longitude = child.toElement().text().toFloat(&ok); + if (ok == false) + { + XMLAnomaly.point.longitude = NODATA; + } nrTokens++; } else if (myTag == "INFO") From 28bea4184f4537a651f4d13b251634ece441f039 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 31 May 2024 17:43:52 +0200 Subject: [PATCH 027/179] fix warnings --- climate/climate.cpp | 2 +- climate/climate.h | 3 +-- drought/drought.cpp | 2 +- synchronicityWidget/interpolationChartView.cpp | 2 +- synchronicityWidget/synchronicityWidget.cpp | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/climate/climate.cpp b/climate/climate.cpp index 137add53..5b179518 100644 --- a/climate/climate.cpp +++ b/climate/climate.cpp @@ -3826,7 +3826,7 @@ bool parseXMLElaboration(Crit3DElabList *listXMLElab, Crit3DAnomalyList *listXML meteoVariable var = getKeyMeteoVarMeteoMap(MapMonthlyMeteoVarToString, variable.toStdString()); if (var != noMeteoVar) { - listXMLDrought->updateVariable(var, listXMLDrought->listVariable().size() - 1); //change var + listXMLDrought->updateVariable(var, int(listXMLDrought->listVariable().size()) - 1); //change var } } if (myTag == "EXPORT") diff --git a/climate/climate.h b/climate/climate.h index 3235fd04..8ab2d66a 100644 --- a/climate/climate.h +++ b/climate/climate.h @@ -165,7 +165,6 @@ void setMpValues(Crit3DMeteoPoint meteoPointGet, Crit3DMeteoPoint* meteoPointSet, QDate myDate, meteoVariable myVar, Crit3DMeteoSettings* meteoSettings); meteoComputation getMeteoCompFromString(std::map map, std::string value); - - //int getClimateIndexFromDate(QDate myDate, period periodType); + #endif // CLIMATE_H diff --git a/drought/drought.cpp b/drought/drought.cpp index cfedf9fa..9ae9a29e 100644 --- a/drought/drought.cpp +++ b/drought/drought.cpp @@ -366,7 +366,7 @@ bool Drought::computeSpeiParameters() if ((float)n / (mySums.size()/12) >= minPerc / 100) { // Sort values - sorting::quicksortAscendingFloat(monthSeries, 0, monthSeries.size()-1); + sorting::quicksortAscendingFloat(monthSeries, 0, int(monthSeries.size())-1); // Compute probability weighted moments probabilityWeightedMoments(monthSeries, n, pwm, 0, 0, false); // Fit a Log Logistic probability function diff --git a/synchronicityWidget/interpolationChartView.cpp b/synchronicityWidget/interpolationChartView.cpp index 5b7645b7..558992d4 100644 --- a/synchronicityWidget/interpolationChartView.cpp +++ b/synchronicityWidget/interpolationChartView.cpp @@ -78,7 +78,7 @@ void InterpolationChartView::drawGraphInterpolation(std::vector values, Q axisX->setRange(QDateTime(myStartDate, QTime(1,0,0),Qt::UTC), QDateTime(myStartDate.addDays(values.size()-1), QTime(1,0,0),Qt::UTC)); if ( values.size() <= 10) { - axisX->setTickCount(values.size()); + axisX->setTickCount(int(values.size())); } else { diff --git a/synchronicityWidget/synchronicityWidget.cpp b/synchronicityWidget/synchronicityWidget.cpp index 878e1095..277f9d47 100644 --- a/synchronicityWidget/synchronicityWidget.cpp +++ b/synchronicityWidget/synchronicityWidget.cpp @@ -191,7 +191,7 @@ void Crit3DSynchronicityWidget::addStationGraph() if ((float)myX.size() / days * 100.0 > minPerc) { - statistics::linearRegression(myX, myY, myX.size(), false, &y_intercept, &trend, &r2); + statistics::linearRegression(myX, myY, int(myX.size()), false, &y_intercept, &trend, &r2); } else { From c5d120f6d9f5cf4a8d658cd87c92b041f76746a7 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 31 May 2024 18:07:22 +0200 Subject: [PATCH 028/179] clean 3D --- project/project.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/project.pro b/project/project.pro index b6188538..dca5f276 100644 --- a/project/project.pro +++ b/project/project.pro @@ -31,7 +31,7 @@ INCLUDEPATH += ../crit3dDate ../mathFunctions ../gis ../meteo \ ../solarRadiation ../interpolation ../utilities \ ../netcdfHandler ../dbMeteoPoints ../outputPoints ../dbMeteoGrid \ ../meteoWidget ../commonDialogs ../commonChartElements ../climate \ - ../proxyWidget ../inOutDataXML ../waterTable + ../proxyWidget ../waterTable SOURCES += \ From 0b121685d6944574bc04f98b33799a6ed53de07d Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 31 May 2024 18:17:01 +0200 Subject: [PATCH 029/179] fix math --- waterTable/waterTable.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 101ab4b9..e1a7dbd6 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -1,6 +1,7 @@ #include "waterTable.h" #include "commonConstants.h" #include "furtherMathFunctions.h" +#include WaterTable::WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, From c36409c1d5d46a3afd098b3cdef893ed638d4394 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 31 May 2024 19:13:26 +0200 Subject: [PATCH 030/179] fix water table chart --- waterTable/waterTable.cpp | 82 +++++++----------------------- waterTable/waterTable.h | 30 ++++++----- waterTable/waterTableChartView.cpp | 14 +++-- 3 files changed, 45 insertions(+), 81 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index e1a7dbd6..0f1a1e64 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -32,50 +32,6 @@ QMap WaterTable::getObsDepths() return well.getObsDepths(); } -QString WaterTable::getError() const -{ - return error; -} - -float WaterTable::getAlpha() const -{ - return alpha; -} - -float WaterTable::getH0() const -{ - return h0; -} - -int WaterTable::getNrDaysPeriod() const -{ - return nrDaysPeriod; -} - -float WaterTable::getR2() const -{ - return R2; -} - -float WaterTable::getRMSE() const -{ - return RMSE; -} - -float WaterTable::getNASH() const -{ - return NASH; -} - -float WaterTable::getEF() const -{ - return EF; -} - -int WaterTable::getNrObsData() const -{ - return nrObsData; -} std::vector WaterTable::getMyDates() const { @@ -303,13 +259,11 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) } // Climatic WaterBalance (CWB) on a nrDaysPeriod -float WaterTable::computeCWB(QDate myDate, int nrDays) +double WaterTable::computeCWB(QDate myDate, int nrDays) { - float sumCWB = 0; + double sumCWB = 0; int nrValidDays = 0; QDate actualDate; - float currentCWB; - float weight; for (int shift = 1; shift<=nrDays; shift++) { actualDate = myDate.addDays(-shift); @@ -320,9 +274,9 @@ float WaterTable::computeCWB(QDate myDate, int nrDays) float prec = precValues[index]; if ( etp != NODATA && prec != NODATA) { - currentCWB = prec - etp; - weight = 1 - (float)shift/nrDays; - sumCWB = sumCWB + currentCWB * weight; + double currentCWB = double(prec - etp); + double weight = 1 - (double)shift/nrDays; + sumCWB += currentCWB * weight; nrValidDays = nrValidDays + 1; } } @@ -333,13 +287,12 @@ float WaterTable::computeCWB(QDate myDate, int nrDays) error = "Few Data"; return NODATA; } + // Climate - float climateCWB = avgDailyCWB * nrDays * 0.5; + double climateCWB = avgDailyCWB * nrDays * 0.5; // conversion: from [mm] to [cm] - float computeCWB = (sumCWB - climateCWB) * 0.1; - - return computeCWB; + return (sumCWB - climateCWB) * 0.1; } @@ -528,18 +481,20 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* int i = keys.indexOf(myDate); if (i != -1) // exact data found { - if (i>0) + if (i > 0) { indexPrev = i - 1; - previousDate = keys[indexPrev]; - previosValue = myDepths[previousDate]; + indexNext = i; } if (i < keys.size()-1) { + indexPrev = i; indexNext = i + 1; - nextDate = keys[indexNext]; - nextValue = myDepths[nextDate]; } + previousDate = keys[indexPrev]; + previosValue = myDepths[previousDate]; + nextDate = keys[indexNext]; + nextValue = myDepths[nextDate]; } else { @@ -599,22 +554,23 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* } } } + if (previousDz != NODATA && nextDz != NODATA) { dT = previousDate.daysTo(nextDate); - *myDelta = previousDz * (1 - (diffWithPrev / dT)) + nextDz * (1 - (diffWithNext / dT)); + *myDelta = previousDz * (1.0 - (float(diffWithPrev) / float(dT))) + nextDz * (1.0 - (float(diffWithNext) / float(dT))); *myDeltaDays = std::min(diffWithPrev, diffWithNext); } else if ( previousDz!= NODATA) { dT = diffWithPrev; - *myDelta = previousDz * std::max((1 - (dT / WATERTABLE_MAXDELTADAYS)), 0); + *myDelta = previousDz * std::max((1.f - (float(dT) / float(WATERTABLE_MAXDELTADAYS))), 0.f); *myDeltaDays = dT; } else if ( nextDz!= NODATA) { dT = diffWithNext; - *myDelta = nextDz * std::max((1 - (dT / WATERTABLE_MAXDELTADAYS)), 0); + *myDelta = nextDz * std::max((1.f - (float(dT) / float(WATERTABLE_MAXDELTADAYS))), 0.f); *myDeltaDays = dT; } else diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 5edc2f2d..19ffb95b 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -28,23 +28,26 @@ class WaterTable bool computeWTClimate(); bool computeETP_allSeries(); bool computeCWBCorrelation(int maxNrDays); - float computeCWB(QDate myDate, int nrDays); + double computeCWB(QDate myDate, int nrDays); bool computeWaterTableIndices(); float getWaterTableDaily(QDate myDate); float getWaterTableClimate(QDate myDate); bool computeWaterTableClimate(QDate currentDate, int yearFrom, int yearTo, float* myValue); bool getWaterTableInterpolation(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays); void computeWaterTableSeries(); - QString getError() const; - float getAlpha() const; - float getH0() const; - int getNrDaysPeriod() const; - float getR2() const; - float getRMSE() const; - float getNASH() const; - float getEF() const; - int getNrObsData() const; + QString getError() const { return error; } + + double getAlpha() const { return alpha; } + double getH0() const { return h0; } + + float getR2() const { return R2; } + float getRMSE() const { return RMSE; } + float getNASH() const { return NASH; } + float getEF() const { return EF; } + + int getNrDaysPeriod() const { return nrDaysPeriod; } + int getNrObsData() const { return nrObsData; } std::vector getMyDates() const; std::vector getMyHindcastSeries() const; @@ -68,8 +71,9 @@ class WaterTable std::vector precValues; int nrDaysPeriod; - float alpha; - float h0; + double alpha; + double h0; + float R2; float RMSE; float NASH; @@ -81,7 +85,7 @@ class WaterTable int nrObsData; bool isCWBEquationReady; - float avgDailyCWB; //[mm] + double avgDailyCWB; //[mm] // graph std::vector myDates; diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index ee800815..cff51555 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -34,7 +34,7 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : void WaterTableChartView::draw(std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths) { - axisY->setMax(300); + axisY->setMax(300); // TODO pass value axisY->setMin(0); axisY->setLabelFormat("%d"); axisY->setTickCount(16); @@ -60,15 +60,19 @@ void WaterTableChartView::draw(std::vector myDates, std::vector my int myDepth = obsDepths[myDates[day]]; obsDepthSeries->append(currentDateTime.toMSecsSinceEpoch(), myDepth); } - else - { - obsDepthSeries->append(currentDateTime.toMSecsSinceEpoch(), -1); - } } chart()->addSeries(obsDepthSeries); + obsDepthSeries->attachAxis(axisX); + obsDepthSeries->attachAxis(axisY); + chart()->addSeries(hindcastSeries); + hindcastSeries->attachAxis(axisX); + hindcastSeries->attachAxis(axisY); + chart()->addSeries(interpolationSeries); + interpolationSeries->attachAxis(axisX); + interpolationSeries->attachAxis(axisY); connect(obsDepthSeries, &QScatterSeries::hovered, this, &WaterTableChartView::tooltipObsDepthSeries); connect(hindcastSeries, &QLineSeries::hovered, this, &WaterTableChartView::tooltipLineSeries); From e2c34587e5b30043d844fcb01749a6a10635f024 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Sun, 2 Jun 2024 10:37:15 +0200 Subject: [PATCH 031/179] makeSeasonalForecastWaterTable TO DO --- waterTable/waterTable.cpp | 25 ++++ waterTable/waterTable.h | 7 ++ weatherGenerator/fileUtility.cpp | 52 ++++++-- weatherGenerator/fileUtility.h | 2 +- weatherGenerator/weatherGenerator.cpp | 170 +++++++++++++++++++++++++- weatherGenerator/weatherGenerator.h | 9 ++ weatherGenerator/weatherGenerator.pro | 2 +- 7 files changed, 249 insertions(+), 18 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 0f1a1e64..d4310e63 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -32,6 +32,31 @@ QMap WaterTable::getObsDepths() return well.getObsDepths(); } +void WaterTable::setInputTMin(const std::vector &newInputTMin) +{ + inputTMin = newInputTMin; +} + +void WaterTable::setInputTMax(const std::vector &newInputTMax) +{ + inputTMax = newInputTMax; +} + +void WaterTable::setInputPrec(const std::vector &newInputPrec) +{ + inputPrec = newInputPrec; +} + +void WaterTable::cleanAllMeteoVector() +{ + inputTMin.clear(); + inputTMax.clear(); + inputPrec.clear();; + etpValues.clear();; + precValues.clear();; +} + + std::vector WaterTable::getMyDates() const { diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 19ffb95b..42e7edb1 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -54,6 +54,13 @@ class WaterTable std::vector getMyInterpolateSeries() const; QMap getObsDepths(); + void cleanAllMeteoVector(); + void setInputTMin(const std::vector &newInputTMin); + + void setInputTMax(const std::vector &newInputTMax); + + void setInputPrec(const std::vector &newInputPrec); + private: Crit3DMeteoSettings meteoSettings; gis::Crit3DGisSettings gisSettings; diff --git a/weatherGenerator/fileUtility.cpp b/weatherGenerator/fileUtility.cpp index 0a481b6b..451a4399 100644 --- a/weatherGenerator/fileUtility.cpp +++ b/weatherGenerator/fileUtility.cpp @@ -175,7 +175,7 @@ bool readMeteoDataCsv (const QString &fileName, char mySeparator, double noData, // Write the output of weather generator: a daily series of tmin, tmax, prec data -bool writeMeteoDataCsv(const QString &fileName, char separator, std::vector &dailyData) +bool writeMeteoDataCsv(const QString &fileName, char separator, std::vector &dailyData, bool isWaterTable) { QFile file(fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { @@ -184,23 +184,49 @@ bool writeMeteoDataCsv(const QString &fileName, char separator, std::vector &dailyData); + bool writeMeteoDataCsv(const QString &fileName, char separator, std::vector &dailyData, bool isWaterTable); #endif // FILEUTILITY_H diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 54d0508b..3eaa877b 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -721,8 +721,6 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno dailyPredictions[tmp].minTemp = dailyObsData->inputTMin[obsIndex]; dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; - //dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() - // in base a wgdoy1 e wgdoy2 aggiungi giorni (vuoti) a watertable if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) @@ -767,6 +765,172 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno // last month of my season int anomalyMonth2 = seasonLastDate.month; + for (unsigned int modelIndex = 0; modelIndex < nrMembers; modelIndex++) + { + // assign anomaly + if ( !assignXMLAnomaly(XMLAnomaly, modelIndex, anomalyMonth1, anomalyMonth2, wGenClimate, wGen)) + { + qDebug() << "Error in Scenario: assignXMLAnomaly returns false"; + return false; + } + + if (modelIndex == nrMembers-1 ) + { + isLastMember = true; + } + // compute seasonal prediction + if (! computeSeasonalPredictions(dailyObsData, wGen, + myPredictionYear, myYear, nrRepetitions, + wgDoy1, wgDoy2, rainfallThreshold, isLastMember, + dailyPredictions, &outputDataLength )) + { + qDebug() << "Error in computeSeasonalPredictions"; + return false; + } + + // next model + myYear = myYear + nrRepetitions; + } + + qDebug() << "\n>>> output:" << outputFileName; + + writeMeteoDataCsv (outputFileName, separator, dailyPredictions, false); + + dailyPredictions.clear(); + + return true; +} + +/*! + * \name makeSeasonalForecastWaterTable + * \brief Generates a time series of daily data (Tmin, Tmax, Prec, Depth) + * for a period of nrYears = numMembers * nrRepetitions + * Different members of anomalies loaded by xml files are added to the climate + * Output is written on outputFileName (csv) +*/ +bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, + TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, + int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, + float rainfallThreshold, WaterTable waterTable) +{ + TweatherGenClimate wGen; + std::vector dailyPredictions; + + Crit3DDate myFirstDatePrediction, seasonFirstDate, seasonLastDate; + + unsigned int nrMembers; // number of models into xml anomaly file + unsigned int nrYears; // number of years of the output series. It is the length of the virtual period where all the previsions (one for each model) are given one after another + unsigned int nrValues; // number of days between the first and the last prediction year + int firstYear, lastYear, myYear; + unsigned int obsIndex; + unsigned int addday = 0; + bool isLastMember = false; + + // it checks if observed data includes the last 9 months before wgDoy1 + int nrDaysBeforeWgDoy1; + if (! checkLastYearDate(dailyObsData->inputFirstDate, dailyObsData->inputLastDate, + dailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) + { + qDebug() << "ERROR: observed data should include at least 9 months before wgDoy1"; + return false; + } + + nrMembers = 0; + for (int i = 0; imodelMember.size(); i++) + { + nrMembers += XMLAnomaly->modelMember[i].toUInt(); + } + + nrYears = nrMembers * unsigned(nrRepetitions); + + firstYear = myPredictionYear; + + // wgDoy1 within myPredictionYear, wgDoy2 within myPredictionYear+1 + if (wgDoy1 < wgDoy2) + lastYear = firstYear + signed(nrYears) - 1; + else + lastYear = firstYear + signed(nrYears); + + seasonFirstDate = getDateFromDoy (myPredictionYear, wgDoy1); + if (wgDoy1 < wgDoy2) + seasonLastDate = getDateFromDoy (myPredictionYear, wgDoy2); + else + seasonLastDate = getDateFromDoy (myPredictionYear+1, wgDoy2); + + myFirstDatePrediction = seasonFirstDate.addDays(-nrDaysBeforeWgDoy1); + + for (int i = myPredictionYear; i <= lastYear; i++) + { + if (isLeapYear(i)) + addday++; + } + + nrValues = nrYears * 365 + addday +1; + if (nrValues <= 0) + { + qDebug() << "ERROR: wrong date"; + return false; + } + + dailyPredictions.resize(nrValues); + + // copy the last 9 months before wgDoy1 + float lastTmax = NODATA; + float lastTmin = NODATA; + Crit3DDate myDate = myFirstDatePrediction; + for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) + { + dailyPredictions[tmp].date = myDate; + obsIndex = difference(dailyObsData->inputFirstDate, dailyPredictions[tmp].date); + dailyPredictions[tmp].minTemp = dailyObsData->inputTMin[obsIndex]; + dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; + dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; + //dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() + // in base a wgdoy1 e wgdoy2 aggiungi giorni (vuoti) a watertable + + if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) + || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) + || (int(dailyPredictions[tmp].prec) == int(NODATA))) + { + if (tmp == 0) + { + qDebug() << "ERROR: Missing data:" << QString::fromStdString(dailyPredictions[tmp].date.toStdString()); + return false; + } + else + { + qDebug() << "WARNING: Missing data:" << QString::fromStdString(dailyPredictions[tmp].date.toStdString()); + + if (int(dailyPredictions[tmp].maxTemp) == int(NODATA)) + dailyPredictions[tmp].maxTemp = lastTmax; + + if (int(dailyPredictions[tmp].minTemp) == int(NODATA)) + dailyPredictions[tmp].minTemp = lastTmin; + + if (int(dailyPredictions[tmp].prec) == int(NODATA)) + dailyPredictions[tmp].prec = 0; + } + } + else + { + lastTmax = dailyPredictions[tmp].maxTemp; + lastTmin = dailyPredictions[tmp].minTemp; + } + ++myDate; + } + + qDebug() << "Observed OK"; + int outputDataLength = nrDaysBeforeWgDoy1; + + // store the climate without anomalies + wGen = wGenClimate; + myYear = firstYear; + + // first month of my season + int anomalyMonth1 = seasonFirstDate.month; + // last month of my season + int anomalyMonth2 = seasonLastDate.month; + for (unsigned int modelIndex = 0; modelIndex < nrMembers; modelIndex++) { // assign anomaly @@ -804,7 +968,7 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno qDebug() << "\n>>> output:" << outputFileName; - writeMeteoDataCsv (outputFileName, separator, dailyPredictions); + writeMeteoDataCsv (outputFileName, separator, dailyPredictions, true); dailyPredictions.clear(); diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index 6495d446..b3bfe457 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -9,6 +9,10 @@ #include "parserXML.h" #endif + #ifndef WATERTABLE_H + #include "waterTable.h" + #endif + struct TinputObsData { Crit3DDate inputFirstDate; @@ -114,6 +118,11 @@ TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, int numRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, float rainfallThreshold); + bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, + TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, + int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, + float rainfallThreshold, WaterTable waterTable); + bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate& wgClimate, int predictionYear, int firstYear, int nrRepetitions, int wgDoy1, int wgDoy2, float minPrec, bool isLastMember, diff --git a/weatherGenerator/weatherGenerator.pro b/weatherGenerator/weatherGenerator.pro index 0d932c35..d75fba51 100644 --- a/weatherGenerator/weatherGenerator.pro +++ b/weatherGenerator/weatherGenerator.pro @@ -28,7 +28,7 @@ win32:{ } -INCLUDEPATH += ../crit3dDate ../mathFunctions +INCLUDEPATH += ../crit3dDate ../mathFunctions ../meteo ../gis ../waterTable SOURCES += \ timeUtility.cpp \ From f7bea52d9cd34335f0f40b9a8d399dc8362c46cf Mon Sep 17 00:00:00 2001 From: lauracosta Date: Sun, 2 Jun 2024 11:14:31 +0200 Subject: [PATCH 032/179] cpopy input values to wt --- weatherGenerator/weatherGenerator.cpp | 36 ++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 3eaa877b..471105c8 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -852,10 +852,17 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS lastYear = firstYear + signed(nrYears); seasonFirstDate = getDateFromDoy (myPredictionYear, wgDoy1); + int daysWg; if (wgDoy1 < wgDoy2) + { seasonLastDate = getDateFromDoy (myPredictionYear, wgDoy2); + daysWg = wgDoy2 - wgDoy1 + 1; + } else + { seasonLastDate = getDateFromDoy (myPredictionYear+1, wgDoy2); + daysWg = wgDoy1 - wgDoy2 + 1; + } myFirstDatePrediction = seasonFirstDate.addDays(-nrDaysBeforeWgDoy1); @@ -877,6 +884,34 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS // copy the last 9 months before wgDoy1 float lastTmax = NODATA; float lastTmin = NODATA; + + // copy values to waterTable + std::vector inputTMin; + std::vector inputTMax; + std::vector inputPrec; + obsIndex = difference(dailyObsData->inputFirstDate, myFirstDatePrediction); + int totDays = nrDaysBeforeWgDoy1 + daysWg; + for (int i = 0; i < totDays; i++) + { + if (i < nrDaysBeforeWgDoy1) + { + inputTMin.push_back(dailyObsData->inputTMin[obsIndex+i]); + inputTMax.push_back(dailyObsData->inputTMax[obsIndex+i]); + inputPrec.push_back(dailyObsData->inputPrecip[obsIndex+i]); + } + else + { + // in base a wgdoy1 e wgdoy2 aggiungo giorni (vuoti) a watertable + inputTMin.push_back(NODATA); + inputTMax.push_back(NODATA); + inputPrec.push_back(NODATA); + } + } + waterTable.setInputTMin(inputTMin); + waterTable.setInputTMax(inputTMax); + waterTable.setInputPrec(inputPrec); + // TO DO + Crit3DDate myDate = myFirstDatePrediction; for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) { @@ -886,7 +921,6 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; //dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() - // in base a wgdoy1 e wgdoy2 aggiungi giorni (vuoti) a watertable if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) From 80b2216f4556f77b4503d95bfeda0229e6ea7b01 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Mon, 3 Jun 2024 13:08:16 +0200 Subject: [PATCH 033/179] copy prev data and compute interpolation --- weatherGenerator/weatherGenerator.cpp | 42 ++++++++++++++++++++------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 471105c8..0597213a 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -895,9 +895,9 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS { if (i < nrDaysBeforeWgDoy1) { - inputTMin.push_back(dailyObsData->inputTMin[obsIndex+i]); - inputTMax.push_back(dailyObsData->inputTMax[obsIndex+i]); - inputPrec.push_back(dailyObsData->inputPrecip[obsIndex+i]); + inputTMin.push_back(dailyObsData->inputTMin[obsIndex+i]); + inputTMax.push_back(dailyObsData->inputTMax[obsIndex+i]); + inputPrec.push_back(dailyObsData->inputPrecip[obsIndex+i]); } else { @@ -910,7 +910,10 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS waterTable.setInputTMin(inputTMin); waterTable.setInputTMax(inputTMax); waterTable.setInputPrec(inputPrec); - // TO DO + waterTable.computeETP_allSeries(); + float myDepth; + float myDelta; + int myDeltaDays; Crit3DDate myDate = myFirstDatePrediction; for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) @@ -920,7 +923,10 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS dailyPredictions[tmp].minTemp = dailyObsData->inputTMin[obsIndex]; dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; - //dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() + if (waterTable.getWaterTableInterpolation(QDate(myDate.year, myDate.month, myDate.day), &myDepth, &myDelta, &myDeltaDays)) + { + dailyPredictions[tmp].waterTableDepth = myDepth; + } if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) || (int(dailyPredictions[tmp].minTemp) == int(NODATA)) @@ -988,13 +994,29 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS return false; } - /* TODO for (int tmp = wgDoy1; tmp < wgDoy2; tmp++) { - // passi a watertable i valori tmin tmax prec da wgdoy1 a wgdoy2 - // calcola etp - // dailyPredictions[tmp].waterTableDepth = waterTable.getWaterTableInterpolation() - }*/ + inputTMin[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].minTemp; + inputTMax[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].maxTemp; + inputPrec[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].prec; + } + // calcola etp + waterTable.cleanAllMeteoVector(); + waterTable.setInputTMin(inputTMin); + waterTable.setInputTMax(inputTMax); + waterTable.setInputPrec(inputPrec); + waterTable.computeETP_allSeries(); + float myDepth; + float myDelta; + int myDeltaDays; + for (int tmp = wgDoy1; tmp < wgDoy2; tmp++) + { + Crit3DDate myDate = dailyPredictions[outputDataLength+tmp].date; + if (waterTable.getWaterTableInterpolation(QDate(myDate.year, myDate.month, myDate.day), &myDepth, &myDelta, &myDeltaDays)) + { + dailyPredictions[outputDataLength+tmp].waterTableDepth = myDepth; + } + } // next model myYear = myYear + nrRepetitions; From c1c5eaa5904a93ed32a5a9542988d9c2ee7cc4c8 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Mon, 3 Jun 2024 14:47:24 +0200 Subject: [PATCH 034/179] fix index --- weatherGenerator/weatherGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 0597213a..3f7b96c4 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -994,7 +994,7 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS return false; } - for (int tmp = wgDoy1; tmp < wgDoy2; tmp++) + for (int tmp = 0; tmp <= daysWg; tmp++) { inputTMin[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].minTemp; inputTMax[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].maxTemp; @@ -1009,7 +1009,7 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS float myDepth; float myDelta; int myDeltaDays; - for (int tmp = wgDoy1; tmp < wgDoy2; tmp++) + for (int tmp = 0; tmp <= daysWg; tmp++) { Crit3DDate myDate = dailyPredictions[outputDataLength+tmp].date; if (waterTable.getWaterTableInterpolation(QDate(myDate.year, myDate.month, myDate.day), &myDepth, &myDelta, &myDeltaDays)) From ced4420abfe906b4f6626603081757732c582802 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Mon, 3 Jun 2024 14:50:39 +0200 Subject: [PATCH 035/179] add separator to csv --- weatherGenerator/fileUtility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weatherGenerator/fileUtility.cpp b/weatherGenerator/fileUtility.cpp index 451a4399..f20933b6 100644 --- a/weatherGenerator/fileUtility.cpp +++ b/weatherGenerator/fileUtility.cpp @@ -204,7 +204,7 @@ bool writeMeteoDataCsv(const QString &fileName, char separator, std::vector Date: Mon, 3 Jun 2024 15:17:09 +0200 Subject: [PATCH 036/179] changes in multiple detrending --- interpolation/interpolation.cpp | 124 ++++++++++++++++++++++++------- project/dialogInterpolation.cpp | 2 +- project/project.cpp | 67 +++++++++++++++-- proxyWidget/localProxyWidget.cpp | 35 ++------- 4 files changed, 167 insertions(+), 61 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 623928b1..8be6e470 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1020,7 +1020,11 @@ void localSelection(vector &inputPoints, vector < float x, float y, Crit3DInterpolationSettings& mySettings) { // search more stations to assure min points with all valid proxies - float ratioMinPoints = float(1.4); + float ratioMinPoints; + if (mySettings.getUseLapseRateCode()) + ratioMinPoints = float(2); + else + ratioMinPoints = float(1.3); unsigned minPoints = unsigned(mySettings.getMinPointsLocalDetrending() * ratioMinPoints); if (inputPoints.size() <= minPoints) { @@ -1692,12 +1696,24 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st Crit3DProxy* elevationProxy = mySettings->getProxy(elevationPos); + //lapse rate code + std::vector elevationPoints = myPoints; + vector::iterator it = elevationPoints.begin(); + + while (it != elevationPoints.end()) + { + if (!checkLapseRateCode(it->lapseRateCode, mySettings->getUseLapseRateCode(), true)) + it = elevationPoints.erase(it); + else + it++; + } + // proxy spatial variability (1st step) double avg, stdDev; unsigned validNr; validNr = 0; - if (proxyValidity(myPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + if (proxyValidity(elevationPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) { elevationCombination.setProxySignificant(elevationPos, true); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); @@ -1720,19 +1736,16 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st unsigned i; bool isValid; float proxyValue; - vector::iterator it = myPoints.begin(); + it = myPoints.begin(); while (it != myPoints.end()) { isValid = true; - if (elevationProxy->getIsSignificant()) + proxyValue = it->getProxyValue(elevationPos); + if (proxyValue == NODATA) { - proxyValue = it->getProxyValue(elevationPos); - if (proxyValue == NODATA) - { isValid = false; break; - } } if (! isValid) @@ -1741,8 +1754,25 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st it++; } + it = elevationPoints.begin(); + while (it != elevationPoints.end()) + { + isValid = true; + proxyValue = it->getProxyValue(elevationPos); + if (proxyValue == NODATA) + { + isValid = false; + break; + } + + if (! isValid) + it = elevationPoints.erase(it); + else + it++; + } + // proxy spatial variability (2nd step) - if (proxyValidity(myPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + if (proxyValidity(elevationPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) { elevationCombination.setProxySignificant(elevationPos, true); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); @@ -1768,12 +1798,15 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st for (i=0; i < myPoints.size(); i++) { - predictors.push_back(myPoints[i].getProxyValue(elevationPos)); - predictands.push_back(myPoints[i].value); - weights.push_back(myPoints[i].regressionWeight); + if (checkLapseRateCode(myPoints[i].lapseRateCode, mySettings->getUseLapseRateCode(), true)) + { + predictors.push_back(myPoints[i].getProxyValue(elevationPos)); + predictands.push_back(myPoints[i].value); + weights.push_back(myPoints[i].regressionWeight); + } } - if (mySettings->getUseLocalDetrending() && myPoints.size() < mySettings->getMinPointsLocalDetrending()) + if (mySettings->getUseLocalDetrending() && elevationPoints.size() < mySettings->getMinPointsLocalDetrending()) { elevationProxy->setIsSignificant(false); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); @@ -1820,7 +1853,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st float detrendValue; for (i = 0; i < myPoints.size(); i++) { - if ((elevationProxy->getIsSignificant())) + if (checkLapseRateCode(myPoints[i].lapseRateCode, mySettings->getUseLapseRateCode(), true)) proxyValue = myPoints[i].getProxyValue(elevationPos); detrendValue = float((*func)(proxyValue, parameters[elevationPos])); @@ -1853,6 +1886,17 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector othersPoints = myPoints; + vector::iterator it = othersPoints.begin(); + while (it != othersPoints.end()) + { + if (!checkLapseRateCode(it->lapseRateCode, mySettings->getUseLapseRateCode(), false)) + it = othersPoints.erase(it); + else + it++; + } + // proxy spatial variability (1st step) double avg, stdDev; unsigned validNr; @@ -1862,7 +1906,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetProxy(pos)->getStdDevThreshold(), avg, stdDev)) + if (proxyValidity(othersPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) { othersCombination.setProxySignificant(pos, true); Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); @@ -1889,7 +1933,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector::iterator it = myPoints.begin(); + it = myPoints.begin(); while (it != myPoints.end()) { @@ -1914,13 +1958,37 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetProxy(pos)->getIsSignificant()) + { + proxyValue = it->getProxyValue(pos); + if (proxyValue == NODATA) + { + isValid = false; + break; + } + } + + if (! isValid) + { + it = othersPoints.erase(it); + } + else { + it++; + } + } + // proxy spatial variability (2nd step) validNr = 0; for (int pos=0; pos < proxyNr; pos++) { if (othersCombination.isProxyActive(pos)) { - if (proxyValidity(myPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) + if (proxyValidity(othersPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) { othersCombination.setProxySignificant(pos, true); Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); @@ -1953,7 +2021,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetUseLapseRateCode(), false)) { proxyValue = myPoints[i].getProxyValue(pos); rowPredictors.push_back(proxyValue); @@ -1964,7 +2032,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetUseLocalDetrending() && myPoints.size() < mySettings->getMinPointsLocalDetrending()) + if (mySettings->getUseLocalDetrending() && othersPoints.size() < mySettings->getMinPointsLocalDetrending()) { Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); for (int pos = 1; pos < proxyNr; pos++) @@ -2007,18 +2075,20 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetUseLapseRateCode(), false)) { - if ((othersCombination.isProxyActive(pos)) && othersCombination.isProxySignificant(pos)) + for (int pos=0; pos < proxyNr; pos++) { - proxyValue = myPoints[i].getProxyValue(pos); - proxyValues.push_back(double(proxyValue)); + if ((othersCombination.isProxyActive(pos)) && othersCombination.isProxySignificant(pos)) + { + proxyValue = myPoints[i].getProxyValue(pos); + proxyValues.push_back(double(proxyValue)); + } } - } - detrendValue = float(functionSum(myFunc, proxyValues, parameters)); - myPoints[i].value -= detrendValue; + detrendValue = float(functionSum(myFunc, proxyValues, parameters)); + myPoints[i].value -= detrendValue; + } } return true; diff --git a/project/dialogInterpolation.cpp b/project/dialogInterpolation.cpp index 542e80c1..90f82f70 100644 --- a/project/dialogInterpolation.cpp +++ b/project/dialogInterpolation.cpp @@ -136,7 +136,7 @@ DialogInterpolation::DialogInterpolation(Project *myProject) layoutDetrending->addWidget(localDetrendingEdit); - QLabel *labelElFunction = new QLabel(tr("Fitting function for elevation:")); + QLabel *labelElFunction = new QLabel(tr("fitting function for elevation")); layoutDetrending->addWidget(labelElFunction); std::map::const_iterator itElFunc; diff --git a/project/project.cpp b/project/project.cpp index 565f2699..27c36cc0 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -687,7 +687,7 @@ bool Project::loadParameters(QString parametersFileName) if (parameters->contains("stddev_threshold")) myProxy->setStdDevThreshold(parameters->value("stddev_threshold").toFloat()); - if (parameters->contains("fitting_parameters")) + /*if (parameters->contains("fitting_parameters")) { unsigned int nrParameters; @@ -704,9 +704,63 @@ bool Project::loadParameters(QString parametersFileName) } myProxy->setFittingParametersRange(StringListToDouble(myList)); + }*/ + + if (getProxyPragaName(name_.toStdString()) == proxyHeight) + { + if (parameters->contains("fitting_function")) + { + std::string elevationFuction = parameters->value("fitting_function").toString().toStdString(); + if (fittingFunctionNames.find(elevationFuction) == fittingFunctionNames.end()) + { + errorString = "Unknown function for elevation. Choose between: piecewise_two, triple_piecewise, free_triple_piecewise."; + return false; + } + else + interpolationSettings.setChosenElevationFunction(fittingFunctionNames.at(elevationFuction)); + + if (parameters->contains("fitting_parameters")) + { + unsigned int nrParameters; + + if (interpolationSettings.getChosenElevationFunction()== piecewiseTwo) + nrParameters = 4; + else if (interpolationSettings.getChosenElevationFunction()== piecewiseThree) + nrParameters = 5; + else if (interpolationSettings.getChosenElevationFunction()== piecewiseThreeFree) + nrParameters = 6; + + myList = parameters->value("fitting_parameters").toStringList(); + if (myList.size() != nrParameters*2) + { + errorString = "Wrong number of fitting parameters for proxy: " + name_; + return false; + } + + myProxy->setFittingParametersRange(StringListToDouble(myList)); + } + } + else + { + interpolationSettings.setChosenElevationFunction(piecewiseTwo); + } } + else + { + if(parameters->contains("fitting_parameters")) + { + unsigned int nrParameters = 2; + myList = parameters->value("fitting_parameters").toStringList(); + if (myList.size() != nrParameters*2) + { + errorString = "Wrong number of fitting parameters for proxy: " + name_; + return false; + } + myProxy->setFittingParametersRange(StringListToDouble(myList)); + } + } if (! parameters->contains("active")) { @@ -2635,11 +2689,12 @@ bool Project::interpolationGrid(meteoVariable myVar, const Crit3DTime& myTime) std::vector proxyValues; proxyValues.resize(unsigned(interpolationSettings.getProxyNr())); - if(!setAllFittingRanges(myCombination, &interpolationSettings)) - { - errorString = "Error in function preInterpolation: \n couldn't set fitting ranges."; - return false; - } + if (interpolationSettings.getUseLocalDetrending()) + if(!setAllFittingRanges(myCombination, &interpolationSettings)) + { + errorString = "Error in function preInterpolation: \n couldn't set fitting ranges."; + return false; + } float interpolatedValue = NODATA; unsigned int i, proxyIndex; diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index a1548980..2c2701b9 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -534,33 +534,14 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree) { - float lapseRateH0 = parameters[proxyPos][0]; - float lapseRateH1 = parameters[proxyPos][0]+parameters[proxyPos][2]; - float lapseRateT0 = parameters[proxyPos][1]; - float lapseRateT1 = parameters[proxyPos][1]+parameters[proxyPos][3]; - float regressionSlope = parameters[proxyPos][4]; - - if (xMin < lapseRateH0) - { - myY = lapseRateT0 + regressionSlope * (xMin - lapseRateH0); - point.setX(xMin); - point.setY(myY); - point_vector.append(point); - } - - point.setX(lapseRateH0); - point.setY(lapseRateT0); - point_vector.append(point); - - point.setX(lapseRateH1); - point.setY(lapseRateT1); - point_vector.append(point); + std::vector xVector; + for (int m = xMin; m < xMax; m += 5) + xVector.push_back(m); - if (xMax > lapseRateH1) + for (int p = 0; p < xVector.size(); p++) { - myY = lapseRateT1 + regressionSlope * (xMax - lapseRateH1); - point.setX(xMax); - point.setY(myY); + point.setX(xVector[p]); + point.setY(lapseRatePiecewiseThree_withSlope(xVector[p], parameters[proxyPos])); point_vector.append(point); } } @@ -588,7 +569,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) point.setY(myY); point_vector.append(point); } - else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree) + else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeFree) { std::vector xVector; for (int m = xMin; m < xMax; m += 5) @@ -597,7 +578,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) for (int p = 0; p < xVector.size(); p++) { point.setX(xVector[p]); - point.setY(lapseRatePiecewiseThree_withSlope(xVector[p], parameters[proxyPos])); + point.setY(lapseRatePiecewiseFree(xVector[p], parameters[proxyPos])); point_vector.append(point); } From f55d9cfd2a50bf08cc60df31cdaeaad70fd26ef1 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 3 Jun 2024 15:36:28 +0200 Subject: [PATCH 037/179] update watertable --- project/project.cpp | 11 +++---- project/project.h | 6 ++-- waterTable/importData.cpp | 4 ++- waterTable/waterTable.cpp | 20 ++++++------- waterTable/waterTable.h | 2 +- waterTable/waterTableChartView.cpp | 5 ++-- waterTable/waterTableChartView.h | 47 +++++++++++++++++------------- waterTable/waterTableWidget.cpp | 5 ++-- waterTable/waterTableWidget.h | 29 +++++++++--------- waterTable/well.cpp | 9 ++++-- waterTable/well.h | 7 +++-- 11 files changed, 80 insertions(+), 65 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 565f2699..0974fac6 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4556,7 +4556,7 @@ bool Project::findTemperatureRange(meteoVariable myVar) } -bool Project::waterTableImportLocation(QString csvFileName) +bool Project::waterTableImportLocation(const QString &csvFileName) { if (logFileName == "") { @@ -4582,10 +4582,10 @@ bool Project::waterTableImportLocation(QString csvFileName) } -bool Project::waterTableImportDepths(QString csvDepths) +bool Project::waterTableImportDepths(const QString &csvDepthsFileName) { int wrongLines = 0; - if (! loadWaterTableDepthCsv(csvDepths, wellPoints, quality->getWaterTableMaximumDepth(), errorString, wrongLines)) + if (! loadWaterTableDepthCsv(csvDepthsFileName, wellPoints, quality->getWaterTableMaximumDepth(), errorString, wrongLines)) { logError(errorString); return false; @@ -4668,11 +4668,12 @@ bool Project::computeSingleWell(int indexWell) } -void Project::showSingleWell(WaterTable waterTable, QString idWell) +void Project::showSingleWell(WaterTable &waterTable, const QString &idWell) { DialogSummary* dialogResult = new DialogSummary(waterTable); // show results dialogResult->show(); - WaterTableWidget* chartResult = new WaterTableWidget(idWell, waterTable.getMyDates(), waterTable.getMyHindcastSeries(), waterTable.getMyInterpolateSeries(), waterTable.getObsDepths()); + WaterTableWidget* chartResult = new WaterTableWidget(idWell, waterTable.getMyDates(), waterTable.getMyHindcastSeries(), + waterTable.getMyInterpolateSeries(), waterTable.getObsDepths(), quality->getWaterTableMaximumDepth()); chartResult->show(); return; } diff --git a/project/project.h b/project/project.h index 8a440705..78fd6f71 100644 --- a/project/project.h +++ b/project/project.h @@ -300,10 +300,10 @@ void setComputeOnlyPoints(bool value); bool getComputeOnlyPoints(); - bool waterTableImportLocation(QString csvFileName); - bool waterTableImportDepths(QString csvDepths); + bool waterTableImportLocation(const QString &csvFileName); + bool waterTableImportDepths(const QString &csvDepthsFileName); bool computeSingleWell(int indexWell); - void showSingleWell(WaterTable waterTable, QString idWell); + void showSingleWell(WaterTable &waterTable, const QString &idWell); bool assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint); bool assignWTMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate); diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index f389c8a0..b336a915 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "well.h" bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines) @@ -173,8 +174,9 @@ bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellL wrongLines++; continue; } + items[posDepth] = items[posDepth].simplified(); - int value = items[posDepth].remove(QChar('"')).toInt(&ok); + float value = items[posDepth].remove(QChar('"')).toFloat(&ok); if (!ok || value == NODATA || value < 0 || value > waterTableMaximumDepth) { errorList.append(line); diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index d4310e63..f3323474 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -27,7 +27,7 @@ QDate WaterTable::getLastDateWell() return lastDateWell; } -QMap WaterTable::getObsDepths() +QMap WaterTable::getObsDepths() { return well.getObsDepths(); } @@ -140,8 +140,8 @@ bool WaterTable::computeWTClimate() H_num.push_back(0); } - QMap myDepths = well.getObsDepths(); - QMapIterator it(myDepths); + QMap myDepths = well.getObsDepths(); + QMapIterator it(myDepths); while (it.hasNext()) { it.next(); @@ -231,7 +231,7 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) float bestH0; float bestAlfaCoeff; int bestNrDays = NODATA; - QMap myDepths = well.getObsDepths(); + QMap myDepths = well.getObsDepths(); std::vector myCWBSum; std::vector myObsWT; float a; @@ -243,7 +243,7 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) { myCWBSum.clear(); myObsWT.clear(); - QMapIterator it(myDepths); + QMapIterator it(myDepths); while (it.hasNext()) { it.next(); @@ -324,8 +324,8 @@ double WaterTable::computeCWB(QDate myDate, int nrDays) // function to compute several statistical indices for watertable depth bool WaterTable::computeWaterTableIndices() { - QMap myDepths = well.getObsDepths(); - QMapIterator it(myDepths); + QMap myDepths = well.getObsDepths(); + QMapIterator it(myDepths); std::vector myObs; std::vector myComputed; std::vector myClimate; @@ -501,7 +501,7 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* int dT; // previuos and next observation - QMap myDepths = well.getObsDepths(); + QMap myDepths = well.getObsDepths(); QList keys = myDepths.keys(); int i = keys.indexOf(myDate); if (i != -1) // exact data found @@ -612,8 +612,8 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* void WaterTable::computeWaterTableSeries() { - QMap myDepths = well.getObsDepths(); - QMapIterator it(myDepths); + QMap myDepths = well.getObsDepths(); + QMapIterator it(myDepths); myDates.clear(); myHindcastSeries.clear(); diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 42e7edb1..9fb1faba 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -52,7 +52,7 @@ class WaterTable std::vector getMyDates() const; std::vector getMyHindcastSeries() const; std::vector getMyInterpolateSeries() const; - QMap getObsDepths(); + QMap getObsDepths(); void cleanAllMeteoVector(); void setInputTMin(const std::vector &newInputTMin); diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index cff51555..c234a92c 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -32,9 +32,10 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : } -void WaterTableChartView::draw(std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths) +void WaterTableChartView::draw(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, + QMap &obsDepths, float maximumObservedDepth) { - axisY->setMax(300); // TODO pass value + axisY->setMax(maximumObservedDepth); // unit of observed watertable data, usually [cm] axisY->setMin(0); axisY->setLabelFormat("%d"); axisY->setTickCount(16); diff --git a/waterTable/waterTableChartView.h b/waterTable/waterTableChartView.h index 8c4d9727..7f8c503c 100644 --- a/waterTable/waterTableChartView.h +++ b/waterTable/waterTableChartView.h @@ -1,27 +1,32 @@ #ifndef WATERTABLECHARTVIEW_H #define WATERTABLECHARTVIEW_H -#include -#include -#include "waterTable.h" -#include "callout.h" + #include + #include + #include "waterTable.h" + #include "callout.h" -class WaterTableChartView : public QChartView -{ - public: - WaterTableChartView(QWidget *parent = 0); - void draw(std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths); - void tooltipObsDepthSeries(QPointF point, bool state); - void tooltipLineSeries(QPointF point, bool state); - void handleMarkerClicked(); - QList exportInterpolationValues(); - private: - QScatterSeries* obsDepthSeries; - QLineSeries* hindcastSeries; - QLineSeries* interpolationSeries; - QDateTimeAxis* axisX; - QValueAxis* axisY; - Callout *m_tooltip; -}; + class WaterTableChartView : public QChartView + { + public: + WaterTableChartView(QWidget *parent = 0); + + void draw(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, + QMap &obsDepths, float maximumObservedDepth); + + void tooltipObsDepthSeries(QPointF point, bool state); + void tooltipLineSeries(QPointF point, bool state); + void handleMarkerClicked(); + QList exportInterpolationValues(); + + private: + QScatterSeries* obsDepthSeries; + QLineSeries* hindcastSeries; + QLineSeries* interpolationSeries; + + QDateTimeAxis* axisX; + QValueAxis* axisY; + Callout *m_tooltip; + }; #endif // WATERTABLECHARTVIEW_H diff --git a/waterTable/waterTableWidget.cpp b/waterTable/waterTableWidget.cpp index be4c5b5d..e36cda8c 100644 --- a/waterTable/waterTableWidget.cpp +++ b/waterTable/waterTableWidget.cpp @@ -1,6 +1,7 @@ #include "waterTableWidget.h" -WaterTableWidget::WaterTableWidget(QString id, std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths) +WaterTableWidget::WaterTableWidget(const QString &id, std::vector &myDates, std::vector &myHindcastSeries, + std::vector &myInterpolateSeries, QMap &obsDepths, float maxObservedDepth) { this->setWindowTitle("Graph Id well: "+ id); this->resize(1240, 700); @@ -28,7 +29,7 @@ WaterTableWidget::WaterTableWidget(QString id, std::vector myDates, std:: connect(exportInterpolation, &QAction::triggered, this, &WaterTableWidget::on_actionExportInterpolationData); - waterTableChartView->draw(myDates, myHindcastSeries, myInterpolateSeries, obsDepths); + waterTableChartView->draw(myDates, myHindcastSeries, myInterpolateSeries, obsDepths, maxObservedDepth); } void WaterTableWidget::on_actionExportInterpolationData() diff --git a/waterTable/waterTableWidget.h b/waterTable/waterTableWidget.h index 90e10261..378e4972 100644 --- a/waterTable/waterTableWidget.h +++ b/waterTable/waterTableWidget.h @@ -1,23 +1,24 @@ #ifndef WATERTABLEWIDGET_H #define WATERTABLEWIDGET_H -#include -#include + #include + #include -#include "waterTableChartView.h" + #include "waterTableChartView.h" -class WaterTableWidget : public QWidget -{ - Q_OBJECT -public: - WaterTableWidget(QString id, std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths); - ~WaterTableWidget(); - void closeEvent(QCloseEvent *event); - void on_actionExportInterpolationData(); + class WaterTableWidget : public QWidget + { + Q_OBJECT + public: + WaterTableWidget(const QString &id, std::vector &myDates, std::vector &myHindcastSeries, + std::vector &myInterpolateSeries, QMap &obsDepths, float maxObservedDepth); + ~WaterTableWidget(); + void closeEvent(QCloseEvent *event); + void on_actionExportInterpolationData(); -private: - WaterTableChartView *waterTableChartView; + private: + WaterTableChartView *waterTableChartView; -}; + }; #endif // WATERTABLEWIDGET_H diff --git a/waterTable/well.cpp b/waterTable/well.cpp index b06cba42..bc3db8c1 100644 --- a/waterTable/well.cpp +++ b/waterTable/well.cpp @@ -36,7 +36,7 @@ void Well::setUtmY(double newUtmY) utmY = newUtmY; } -void Well::insertData(QDate myDate, int myValue) +void Well::insertData(QDate myDate, float myValue) { depths.insert(myDate, myValue); } @@ -46,11 +46,13 @@ int Well::getObsDepthNr() return depths.size(); } -QMap Well::getObsDepths() const + +QMap Well::getObsDepths() const { return depths; } + QDate Well::getFirstDate() { QList allDates = depths.keys(); @@ -79,9 +81,10 @@ QDate Well::getLastDate() return lastDate; } + int Well::minValuesPerMonth() { - QMapIterator it(depths); + QMapIterator it(depths); std::vector H_num; for (int myMonthIndex = 0; myMonthIndex < 12; myMonthIndex++) { diff --git a/waterTable/well.h b/waterTable/well.h index 36a5ee04..c7c86feb 100644 --- a/waterTable/well.h +++ b/waterTable/well.h @@ -19,21 +19,22 @@ class Well double getUtmY() const; void setUtmY(double newUtmY); - void insertData(QDate myDate, int myValue); + void insertData(QDate myDate, float myValue); QDate getFirstDate(); QDate getLastDate(); int getObsDepthNr(); - QMap getObsDepths() const; + QMap getObsDepths() const; + int minValuesPerMonth(); private: QString id; double utmX; double utmY; - QMap depths; + QMap depths; QDate firstDate; QDate lastDate; }; From c909e195d1f52ccd8326ab906d5696c95146d035 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 3 Jun 2024 15:44:08 +0200 Subject: [PATCH 038/179] update watertable --- project/project.cpp | 3 ++- waterTable/waterTableChartView.cpp | 2 +- waterTable/waterTableChartView.h | 2 +- waterTable/waterTableWidget.cpp | 4 ++-- waterTable/waterTableWidget.h | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 0ae1c413..ffc9e43f 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4728,7 +4728,8 @@ void Project::showSingleWell(WaterTable &waterTable, const QString &idWell) DialogSummary* dialogResult = new DialogSummary(waterTable); // show results dialogResult->show(); WaterTableWidget* chartResult = new WaterTableWidget(idWell, waterTable.getMyDates(), waterTable.getMyHindcastSeries(), - waterTable.getMyInterpolateSeries(), waterTable.getObsDepths(), quality->getWaterTableMaximumDepth()); + waterTable.getMyInterpolateSeries(), waterTable.getObsDepths(), + quality->getWaterTableMaximumDepth()); chartResult->show(); return; } diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index c234a92c..b79d8ee3 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -33,7 +33,7 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : void WaterTableChartView::draw(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, - QMap &obsDepths, float maximumObservedDepth) + QMap obsDepths, float maximumObservedDepth) { axisY->setMax(maximumObservedDepth); // unit of observed watertable data, usually [cm] axisY->setMin(0); diff --git a/waterTable/waterTableChartView.h b/waterTable/waterTableChartView.h index 7f8c503c..879bc998 100644 --- a/waterTable/waterTableChartView.h +++ b/waterTable/waterTableChartView.h @@ -12,7 +12,7 @@ WaterTableChartView(QWidget *parent = 0); void draw(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, - QMap &obsDepths, float maximumObservedDepth); + QMap obsDepths, float maximumObservedDepth); void tooltipObsDepthSeries(QPointF point, bool state); void tooltipLineSeries(QPointF point, bool state); diff --git a/waterTable/waterTableWidget.cpp b/waterTable/waterTableWidget.cpp index e36cda8c..4e436999 100644 --- a/waterTable/waterTableWidget.cpp +++ b/waterTable/waterTableWidget.cpp @@ -1,7 +1,7 @@ #include "waterTableWidget.h" -WaterTableWidget::WaterTableWidget(const QString &id, std::vector &myDates, std::vector &myHindcastSeries, - std::vector &myInterpolateSeries, QMap &obsDepths, float maxObservedDepth) +WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates, std::vector &myHindcastSeries, + std::vector &myInterpolateSeries, QMap obsDepths, float maxObservedDepth) { this->setWindowTitle("Graph Id well: "+ id); this->resize(1240, 700); diff --git a/waterTable/waterTableWidget.h b/waterTable/waterTableWidget.h index 378e4972..eb2b669c 100644 --- a/waterTable/waterTableWidget.h +++ b/waterTable/waterTableWidget.h @@ -10,8 +10,8 @@ { Q_OBJECT public: - WaterTableWidget(const QString &id, std::vector &myDates, std::vector &myHindcastSeries, - std::vector &myInterpolateSeries, QMap &obsDepths, float maxObservedDepth); + WaterTableWidget(const QString &id, std::vector myDates, std::vector &myHindcastSeries, + std::vector &myInterpolateSeries, QMap obsDepths, float maxObservedDepth); ~WaterTableWidget(); void closeEvent(QCloseEvent *event); void on_actionExportInterpolationData(); From b7d4038522d969585ad33877900b58636d12afea Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Mon, 3 Jun 2024 15:53:53 +0200 Subject: [PATCH 039/179] correzione inizializzazione wGen --- weatherGenerator/parserXML.cpp | 4 ++-- weatherGenerator/parserXML.h | 2 +- weatherGenerator/weatherGenerator.cpp | 22 +++++++++++----------- weatherGenerator/weatherGenerator.h | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/weatherGenerator/parserXML.cpp b/weatherGenerator/parserXML.cpp index 12846790..6907f157 100644 --- a/weatherGenerator/parserXML.cpp +++ b/weatherGenerator/parserXML.cpp @@ -330,7 +330,7 @@ bool parseXMLScenario(const QString &xmlFileName, XMLScenarioAnomaly &XMLAnomaly QDomNode child; QDomNode secondChild; - TXMLValuesList valuelist; + TXMLScenarioValuesList valuelist; QDomNode ancestor = xmlDoc.documentElement().firstChild(); QString myTag; @@ -463,7 +463,7 @@ bool parseXMLScenario(const QString &xmlFileName, XMLScenarioAnomaly &XMLAnomaly if (myTag == "VAR") { secondChild = child.firstChild(); - + XMLAnomaly.period[counterTime].seasonalScenarios.push_back(valuelist); while(! secondChild.isNull()) { mySecondTag = secondChild.toElement().tagName().toUpper(); diff --git a/weatherGenerator/parserXML.h b/weatherGenerator/parserXML.h index 9e56ca20..71eead4b 100644 --- a/weatherGenerator/parserXML.h +++ b/weatherGenerator/parserXML.h @@ -39,7 +39,7 @@ struct TXMLScenarioPeriod { QString type; - TXMLScenarioValuesList seasonalScenarios[4]; + std::vector seasonalScenarios; }; struct TXMLPoint diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 471105c8..e6d45c17 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -554,7 +554,7 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, return true; } -bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int anomalyMonth1, int anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) +bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int* anomalyMonth1, int* anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) { //unsigned int i = 0; QString myVar; @@ -579,17 +579,17 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int if (int(myValue) != int(NODATA)) { if ( (myVar == "TMIN") || (myVar == "AVGTMIN") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmin, wGen.monthly.monthlyTmin); + result = assignAnomalyNoPrec(myValue, anomalyMonth1[iSeason], anomalyMonth2[iSeason], wGenNoAnomaly.monthly.monthlyTmin, wGen.monthly.monthlyTmin); else if ( (myVar == "TMAX") || (myVar == "AVGTMAX") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.monthlyTmax, wGen.monthly.monthlyTmax); + result = assignAnomalyNoPrec(myValue, anomalyMonth1[iSeason], anomalyMonth2[iSeason], wGenNoAnomaly.monthly.monthlyTmax, wGen.monthly.monthlyTmax); else if ( (myVar == "PREC3M") || (myVar == "PREC") ) - result = assignAnomalyPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.sumPrec, wGen.monthly.sumPrec); + result = assignAnomalyPrec(myValue, anomalyMonth1[iSeason], anomalyMonth2[iSeason], wGenNoAnomaly.monthly.sumPrec, wGen.monthly.sumPrec); else if ( (myVar == "WETDAYSFREQUENCY") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.fractionWetDays, wGen.monthly.fractionWetDays); + result = assignAnomalyNoPrec(myValue, anomalyMonth1[iSeason], anomalyMonth2[iSeason], wGenNoAnomaly.monthly.fractionWetDays, wGen.monthly.fractionWetDays); else if ( (myVar == "WETWETDAYSFREQUENCY") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.probabilityWetWet, wGen.monthly.probabilityWetWet); + result = assignAnomalyNoPrec(myValue, anomalyMonth1[iSeason], anomalyMonth2[iSeason], wGenNoAnomaly.monthly.probabilityWetWet, wGen.monthly.probabilityWetWet); else if ( (myVar == "DELTATMAXDRYWET") ) - result = assignAnomalyNoPrec(myValue, anomalyMonth1, anomalyMonth2, wGenNoAnomaly.monthly.dw_Tmax, wGen.monthly.dw_Tmax); + result = assignAnomalyNoPrec(myValue, anomalyMonth1[iSeason], anomalyMonth2[iSeason], wGenNoAnomaly.monthly.dw_Tmax, wGen.monthly.dw_Tmax); } @@ -609,10 +609,10 @@ bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int } } // move to the next season - anomalyMonth1 = (anomalyMonth1 + 3)%12; - if (anomalyMonth1 == 0) anomalyMonth1 +=12; - anomalyMonth2 = (anomalyMonth2 + 3)%12; - if (anomalyMonth2 == 0) anomalyMonth2 +=12; + //anomalyMonth1 = (anomalyMonth1 + 3)%12; + //if (anomalyMonth1 == 0) anomalyMonth1 +=12; + //anomalyMonth2 = (anomalyMonth2 + 3)%12; + //if (anomalyMonth2 == 0) anomalyMonth2 +=12; } /* DEBUG QString anomaly="anomaly.txt"; diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index b3bfe457..c9f68890 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -111,7 +111,7 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, float* myWGMonthlyVarNoAnomaly, float* myWGMonthlyVar); - bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int modelIndex, int anomalyMonth1, int anomalyMonth2, + bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly, int modelIndex, int *anomalyMonth1, int *anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen); bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, From dce82c662883505f574193106d0d88381ae34caf Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 3 Jun 2024 16:01:52 +0200 Subject: [PATCH 040/179] fix watertable --- waterTable/waterTable.cpp | 7 +++---- waterTable/waterTable.h | 6 +++--- waterTable/waterTableWidget.cpp | 4 ++-- waterTable/waterTableWidget.h | 4 ++-- waterTable/well.cpp | 2 +- waterTable/well.h | 2 +- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index f3323474..c2c79c06 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -57,18 +57,17 @@ void WaterTable::cleanAllMeteoVector() } - -std::vector WaterTable::getMyDates() const +std::vector WaterTable::getMyDates() { return myDates; } -std::vector WaterTable::getMyHindcastSeries() const +std::vector WaterTable::getMyHindcastSeries() { return myHindcastSeries; } -std::vector WaterTable::getMyInterpolateSeries() const +std::vector WaterTable::getMyInterpolateSeries() { return myInterpolateSeries; } diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 9fb1faba..10210eb1 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -49,9 +49,9 @@ class WaterTable int getNrDaysPeriod() const { return nrDaysPeriod; } int getNrObsData() const { return nrObsData; } - std::vector getMyDates() const; - std::vector getMyHindcastSeries() const; - std::vector getMyInterpolateSeries() const; + std::vector getMyDates(); + std::vector getMyHindcastSeries(); + std::vector getMyInterpolateSeries(); QMap getObsDepths(); void cleanAllMeteoVector(); diff --git a/waterTable/waterTableWidget.cpp b/waterTable/waterTableWidget.cpp index 4e436999..b8e4bec8 100644 --- a/waterTable/waterTableWidget.cpp +++ b/waterTable/waterTableWidget.cpp @@ -1,7 +1,7 @@ #include "waterTableWidget.h" -WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates, std::vector &myHindcastSeries, - std::vector &myInterpolateSeries, QMap obsDepths, float maxObservedDepth) +WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates, std::vector myHindcastSeries, + std::vector myInterpolateSeries, QMap obsDepths, float maxObservedDepth) { this->setWindowTitle("Graph Id well: "+ id); this->resize(1240, 700); diff --git a/waterTable/waterTableWidget.h b/waterTable/waterTableWidget.h index eb2b669c..cb43494d 100644 --- a/waterTable/waterTableWidget.h +++ b/waterTable/waterTableWidget.h @@ -10,8 +10,8 @@ { Q_OBJECT public: - WaterTableWidget(const QString &id, std::vector myDates, std::vector &myHindcastSeries, - std::vector &myInterpolateSeries, QMap obsDepths, float maxObservedDepth); + WaterTableWidget(const QString &id, std::vector myDates, std::vector myHindcastSeries, + std::vector myInterpolateSeries, QMap obsDepths, float maxObservedDepth); ~WaterTableWidget(); void closeEvent(QCloseEvent *event); void on_actionExportInterpolationData(); diff --git a/waterTable/well.cpp b/waterTable/well.cpp index bc3db8c1..9e6f3c11 100644 --- a/waterTable/well.cpp +++ b/waterTable/well.cpp @@ -47,7 +47,7 @@ int Well::getObsDepthNr() } -QMap Well::getObsDepths() const +QMap Well::getObsDepths() { return depths; } diff --git a/waterTable/well.h b/waterTable/well.h index c7c86feb..57afd074 100644 --- a/waterTable/well.h +++ b/waterTable/well.h @@ -26,7 +26,7 @@ class Well int getObsDepthNr(); - QMap getObsDepths() const; + QMap getObsDepths(); int minValuesPerMonth(); From 502b6d7323bf4589f92685e92e3d457f53a56c52 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 3 Jun 2024 16:23:01 +0200 Subject: [PATCH 041/179] fix watertable --- waterTable/waterTableChartView.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index b79d8ee3..30891b63 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -64,14 +64,13 @@ void WaterTableChartView::draw(std::vector &myDates, std::vector & } chart()->addSeries(obsDepthSeries); + chart()->addSeries(hindcastSeries); + chart()->addSeries(interpolationSeries); + obsDepthSeries->attachAxis(axisX); obsDepthSeries->attachAxis(axisY); - - chart()->addSeries(hindcastSeries); hindcastSeries->attachAxis(axisX); hindcastSeries->attachAxis(axisY); - - chart()->addSeries(interpolationSeries); interpolationSeries->attachAxis(axisX); interpolationSeries->attachAxis(axisY); From bf578ad08556ffc8c05076632902031e355e825f Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 3 Jun 2024 17:33:27 +0200 Subject: [PATCH 042/179] update description --- weatherGenerator/weatherGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 62e37eca..e9a359e6 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -5,7 +5,7 @@ \copyright 2016 Fausto Tomei, Laura Costantini - This file is part of CRITERIA3D. + This file is part of agrolib distribution . CRITERIA3D has been developed under contract issued by A.R.P.A. Emilia-Romagna CRITERIA3D is free software: you can redistribute it and/or modify From 27ce6de124643e20910928110a4981431029a334 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Tue, 4 Jun 2024 12:14:33 +0200 Subject: [PATCH 043/179] to check copy data waterTable outside wg --- weatherGenerator/weatherGenerator.cpp | 72 ++++++++++++++++++--------- weatherGenerator/weatherGenerator.h | 2 +- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index e9a359e6..91bd4635 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -779,10 +779,11 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno isLastMember = true; } // compute seasonal prediction + std::vector indexWg; if (! computeSeasonalPredictions(dailyObsData, wGen, myPredictionYear, myYear, nrRepetitions, wgDoy1, wgDoy2, rainfallThreshold, isLastMember, - dailyPredictions, &outputDataLength )) + dailyPredictions, &outputDataLength, indexWg)) { qDebug() << "Error in computeSeasonalPredictions"; return false; @@ -958,7 +959,6 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS } ++myDate; } - qDebug() << "Observed OK"; int outputDataLength = nrDaysBeforeWgDoy1; @@ -985,45 +985,68 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS isLastMember = true; } // compute seasonal prediction + std::vector indexWg; if (! computeSeasonalPredictions(dailyObsData, wGen, myPredictionYear, myYear, nrRepetitions, wgDoy1, wgDoy2, rainfallThreshold, isLastMember, - dailyPredictions, &outputDataLength )) + dailyPredictions, &outputDataLength, indexWg)) { qDebug() << "Error in computeSeasonalPredictions"; return false; } - for (int tmp = 0; tmp <= daysWg; tmp++) - { - inputTMin[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].minTemp; - inputTMax[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].maxTemp; - inputPrec[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[outputDataLength+tmp].prec; - } - // calcola etp - waterTable.cleanAllMeteoVector(); - waterTable.setInputTMin(inputTMin); - waterTable.setInputTMax(inputTMax); - waterTable.setInputPrec(inputPrec); - waterTable.computeETP_allSeries(); - float myDepth; - float myDelta; - int myDeltaDays; - for (int tmp = 0; tmp <= daysWg; tmp++) + if (indexWg.size() != 0) { - Crit3DDate myDate = dailyPredictions[outputDataLength+tmp].date; - if (waterTable.getWaterTableInterpolation(QDate(myDate.year, myDate.month, myDate.day), &myDepth, &myDelta, &myDeltaDays)) + //qDebug() << "indexWg[0] " << indexWg[0]; + //qDebug() << "indexWg [indexWg.size()-1] " << indexWg [indexWg.size()-1]; + //int nWgDays = indexWg [indexWg.size()-1] - indexWg[0]; + //qDebug() << "nWgDays " << nWgDays; + for (int tmp = 0; tmp < daysWg; tmp++) + { + inputTMin[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[indexWg[0]+tmp].minTemp; + inputTMax[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[indexWg[0]+tmp].maxTemp; + inputPrec[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[indexWg[0]+tmp].prec; + } + // calcola etp + waterTable.cleanAllMeteoVector(); + waterTable.setInputTMin(inputTMin); + waterTable.setInputTMax(inputTMax); + waterTable.setInputPrec(inputPrec); + waterTable.computeETP_allSeries(); + float myDepth; + float myDelta; + int myDeltaDays; + QDate myDate(seasonFirstDate.year, seasonFirstDate.month, seasonFirstDate.day); + for (int tmp = 0; tmp < daysWg; tmp++) { - dailyPredictions[outputDataLength+tmp].waterTableDepth = myDepth; + if (waterTable.getWaterTableInterpolation(myDate, &myDepth, &myDelta, &myDeltaDays)) + { + dailyPredictions[indexWg[0]+tmp].waterTableDepth = myDepth; + } + myDate = myDate.addDays(1); } } // next model myYear = myYear + nrRepetitions; } - qDebug() << "\n>>> output:" << outputFileName; + int fixWgDoy1 = wgDoy1; + int fixWgDoy2 = wgDoy2; + int index = 0; + for (myDate = dailyPredictions[0].date; myDate <= dailyPredictions[dailyPredictions.size()-1].date; myDate=myDate.addDays(1)) + { + setCorrectWgDoy(wgDoy1, wgDoy2, myPredictionYear, myDate.year, fixWgDoy1, fixWgDoy2); + if ( !isWGDate(myDate, fixWgDoy1, fixWgDoy2) && dailyPredictions[index].waterTableDepth == NODATA) + { + int indexToBeCopyed = 0; + dailyPredictions[index].waterTableDepth = dailyPredictions[indexToBeCopyed].waterTableDepth; + indexToBeCopyed = indexToBeCopyed + 1; + } + index = index + 1; + } + writeMeteoDataCsv (outputFileName, separator, dailyPredictions, true); dailyPredictions.clear(); @@ -1045,7 +1068,7 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate &wgClimate, int predictionYear, int firstYear, int nrRepetitions, int wgDoy1, int wgDoy2, float rainfallThreshold, bool isLastMember, - std::vector& outputDailyData, int *outputDataLength) + std::vector& outputDailyData, int *outputDataLength, std::vector& indexWg) { Crit3DDate myDate, obsDate; @@ -1124,6 +1147,7 @@ bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate outputDailyData[currentIndex].maxTemp = getTMax(myDoy, rainfallThreshold, wgClimate); outputDailyData[currentIndex].minTemp = getTMin(myDoy, rainfallThreshold, wgClimate); outputDailyData[currentIndex].prec = getPrecip(myDoy, rainfallThreshold, wgClimate); + indexWg.push_back(currentIndex); } else { diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index c9f68890..2994b8a0 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -126,7 +126,7 @@ bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate& wgClimate, int predictionYear, int firstYear, int nrRepetitions, int wgDoy1, int wgDoy2, float minPrec, bool isLastMember, - std::vector &outputDailyData, int *outputDataLength); + std::vector &outputDailyData, int *outputDataLength, std::vector &indexWg); bool computeClimate(TweatherGenClimate &wgClimate, int firstYear, int nrRepetitions, float rainfallThreshold, std::vector &outputDailyData); From 10b2d3e7d9734e3cf06838241ab57142709f3f54 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Tue, 4 Jun 2024 13:02:05 +0200 Subject: [PATCH 044/179] copy data waterTable outside wg --- weatherGenerator/weatherGenerator.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 91bd4635..d1f5850a 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1035,15 +1035,23 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS int fixWgDoy1 = wgDoy1; int fixWgDoy2 = wgDoy2; int index = 0; - for (myDate = dailyPredictions[0].date; myDate <= dailyPredictions[dailyPredictions.size()-1].date; myDate=myDate.addDays(1)) + QDate firstDate(myPredictionYear,1,1); + QDate lastDate(lastYear,12,31); + qDebug() << "firstDate " << firstDate.toString(); + qDebug() << "lastDate " << lastDate.toString(); + int indexToBeCopyed = 0; + for (QDate myDate = firstDate; myDate <= lastDate; myDate=myDate.addDays(1)) { - setCorrectWgDoy(wgDoy1, wgDoy2, myPredictionYear, myDate.year, fixWgDoy1, fixWgDoy2); - if ( !isWGDate(myDate, fixWgDoy1, fixWgDoy2) && dailyPredictions[index].waterTableDepth == NODATA) + setCorrectWgDoy(wgDoy1, wgDoy2, myPredictionYear, myDate.year(), fixWgDoy1, fixWgDoy2); + if ( !isWGDate(Crit3DDate(myDate.day(), myDate.month(), myDate.year()), fixWgDoy1, fixWgDoy2) && dailyPredictions[index].waterTableDepth == NODATA) { - int indexToBeCopyed = 0; dailyPredictions[index].waterTableDepth = dailyPredictions[indexToBeCopyed].waterTableDepth; indexToBeCopyed = indexToBeCopyed + 1; } + else + { + indexToBeCopyed = 0; + } index = index + 1; } From a4a578c582c4486090272b2253a02dae5b30e903 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 4 Jun 2024 15:06:48 +0200 Subject: [PATCH 045/179] update --- weatherGenerator/parserXML.cpp | 31 ++++++++++----------------- weatherGenerator/parserXML.h | 1 + weatherGenerator/weatherGenerator.cpp | 1 + weatherGenerator/wgClimate.cpp | 4 ++-- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/weatherGenerator/parserXML.cpp b/weatherGenerator/parserXML.cpp index 6907f157..a019b61c 100644 --- a/weatherGenerator/parserXML.cpp +++ b/weatherGenerator/parserXML.cpp @@ -52,54 +52,44 @@ void XMLSeasonalAnomaly::printInfo() qDebug() << ""; } + XMLScenarioAnomaly::XMLScenarioAnomaly() { - this->initialize(); // chiedere a Fausto perchรฉ non fare initialize direttamente qui + this->initialize(); } void XMLScenarioAnomaly::initialize() { - /* point.name = ""; point.code = ""; point.latitude = NODATA; point.longitude = NODATA; - point.info = ""; - - forecast.clear(); climatePeriod.yearFrom = NODATA; climatePeriod.yearTo = NODATA; - modelNumber = NODATA; - - modelName.clear(); - modelMember.clear(); + models.type.clear(); + models.value.clear(); + models.number = 0; repetitions = NODATA; anomalyYear = NODATA; - anomalySeason = ""; - */ } void XMLScenarioAnomaly::printInfo() { - /* qDebug() << "point.name = " << point.name; - qDebug() << "point.longitude = " << point.longitude; - qDebug() << "point.latitude = " << point.latitude; + //qDebug() << "point.longitude = " << point.longitude; + //qDebug() << "point.latitude = " << point.latitude; qDebug() << "climate first year = " << climatePeriod.yearFrom; qDebug() << "climate last year = " << climatePeriod.yearTo; - qDebug() << "number of models = " << modelNumber; - qDebug() << "models = " << modelName; - qDebug() << "number of members = " << modelMember; - qDebug() << "number of repetitions = " << repetitions; + qDebug() << "models = " << models.type; + qDebug() << "number of models = " << models.number; qDebug() << "anomaly year = " << anomalyYear; - qDebug() << "anomaly season = " << anomalySeason; + qDebug() << "number of repetitions = " << repetitions; qDebug() << ""; - */ } @@ -399,6 +389,7 @@ bool parseXMLScenario(const QString &xmlFileName, XMLScenarioAnomaly &XMLAnomaly { models = child.toElement().text(); XMLAnomaly.models.value = models.split(","); + XMLAnomaly.models.number = XMLAnomaly.models.value.size(); nrTokens++; } child = child.nextSibling(); diff --git a/weatherGenerator/parserXML.h b/weatherGenerator/parserXML.h index 71eead4b..a6f42f06 100644 --- a/weatherGenerator/parserXML.h +++ b/weatherGenerator/parserXML.h @@ -18,6 +18,7 @@ { QString type; QStringList value; + int number; }; struct TXMLScenarioClimateField { diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index d1f5850a..3517d9fa 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -554,6 +554,7 @@ bool assignAnomalyPrec(float myAnomaly, int anomalyMonth1, int anomalyMonth2, return true; } + bool assignXMLAnomalyScenario(XMLScenarioAnomaly* XMLAnomaly,int modelIndex, int* anomalyMonth1, int* anomalyMonth2, TweatherGenClimate& wGenNoAnomaly, TweatherGenClimate &wGen) { //unsigned int i = 0; diff --git a/weatherGenerator/wgClimate.cpp b/weatherGenerator/wgClimate.cpp index 11312849..a9743c08 100644 --- a/weatherGenerator/wgClimate.cpp +++ b/weatherGenerator/wgClimate.cpp @@ -561,8 +561,8 @@ bool computeWG2DClimate(int nrDays, Crit3DDate inputFirstDate, float *inputTMin, /*! * \brief Generates a climate starting from daily weather */ -bool climateGenerator(int nrData, TinputObsData climateDailyObsData, Crit3DDate climateDateIni, Crit3DDate climateDateFin, float precThreshold, float minPrecData, TweatherGenClimate* wGen) - +bool climateGenerator(int nrData, TinputObsData climateDailyObsData, Crit3DDate climateDateIni, + Crit3DDate climateDateFin, float precThreshold, float minPrecData, TweatherGenClimate* wGen) { unsigned int nrDays; int startIndex; From 90cd20ddb5273c2a8dd04a9b2604d8df17d7da52 Mon Sep 17 00:00:00 2001 From: Antonio Volta Date: Wed, 5 Jun 2024 10:47:05 +0200 Subject: [PATCH 046/179] settaggio Scenario molteplici modelli --- weatherGenerator/timeUtility.cpp | 33 +++++++++++++++++++++++++++ weatherGenerator/timeUtility.h | 2 ++ weatherGenerator/weatherGenerator.cpp | 1 + 3 files changed, 36 insertions(+) diff --git a/weatherGenerator/timeUtility.cpp b/weatherGenerator/timeUtility.cpp index 84b1b2a6..e6ae768a 100644 --- a/weatherGenerator/timeUtility.cpp +++ b/weatherGenerator/timeUtility.cpp @@ -189,3 +189,36 @@ void setCorrectWgDoy(int wgDoy1, int wgDoy2, int predictionYear, int myYear, int } } } + +void setAnomalyMonthScenario(QString startingSeason, int *anomalyMonth1, int *anomalyMonth2) +{ + if(startingSeason == "DJF") + { + anomalyMonth1[0] = 12; anomalyMonth2[0] = 2; + anomalyMonth1[1] = 3; anomalyMonth2[1] = 5; + anomalyMonth1[2] = 6; anomalyMonth2[2] = 8; + anomalyMonth1[3] = 9; anomalyMonth2[3] = 11; + } + else if (startingSeason == "MAM") + { + anomalyMonth1[3] = 12; anomalyMonth2[3] = 2; + anomalyMonth1[0] = 3; anomalyMonth2[0] = 5; + anomalyMonth1[1] = 6; anomalyMonth2[1] = 8; + anomalyMonth1[2] = 9; anomalyMonth2[2] = 11; + } + else if (startingSeason == "JJA") + { + anomalyMonth1[2] = 12; anomalyMonth2[2] = 2; + anomalyMonth1[3] = 3; anomalyMonth2[3] = 5; + anomalyMonth1[0] = 6; anomalyMonth2[0] = 8; + anomalyMonth1[1] = 9; anomalyMonth2[1] = 11; + + } + else + { + anomalyMonth1[1] = 12; anomalyMonth2[1] = 2; + anomalyMonth1[2] = 3; anomalyMonth2[2] = 5; + anomalyMonth1[3] = 6; anomalyMonth2[3] = 8; + anomalyMonth1[0] = 9; anomalyMonth2[0] = 11; + } +} diff --git a/weatherGenerator/timeUtility.h b/weatherGenerator/timeUtility.h index 6d8bb385..aa63fa05 100644 --- a/weatherGenerator/timeUtility.h +++ b/weatherGenerator/timeUtility.h @@ -16,5 +16,7 @@ void setCorrectWgDoy(int wgDoy1, int wgDoy2, int predictionYear, int myYear, int &fixedWgDoy1, int &fixedWgDoy2); + void setAnomalyMonthScenario(QString startingSeason, int *anomalyMonth1, int *anomalyMonth2); + #endif // TIMEUTILITY diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 3517d9fa..9d1b7c71 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1229,3 +1229,4 @@ bool computeClimate(TweatherGenClimate &wgClimate, int firstYear, int nrRepetiti return true; } + From a9d260e0e7078b2f18ad13efaa487483149bcce0 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 5 Jun 2024 11:26:48 +0200 Subject: [PATCH 047/179] fix copy data outside wg --- weatherGenerator/weatherGenerator.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 3517d9fa..e1cfc8e1 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1033,25 +1033,27 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS } qDebug() << "\n>>> output:" << outputFileName; + + // copy all waterTableDepth outside wg period int fixWgDoy1 = wgDoy1; int fixWgDoy2 = wgDoy2; int index = 0; QDate firstDate(myPredictionYear,1,1); QDate lastDate(lastYear,12,31); - qDebug() << "firstDate " << firstDate.toString(); - qDebug() << "lastDate " << lastDate.toString(); - int indexToBeCopyed = 0; + for (QDate myDate = firstDate; myDate <= lastDate; myDate=myDate.addDays(1)) { setCorrectWgDoy(wgDoy1, wgDoy2, myPredictionYear, myDate.year(), fixWgDoy1, fixWgDoy2); if ( !isWGDate(Crit3DDate(myDate.day(), myDate.month(), myDate.year()), fixWgDoy1, fixWgDoy2) && dailyPredictions[index].waterTableDepth == NODATA) { - dailyPredictions[index].waterTableDepth = dailyPredictions[indexToBeCopyed].waterTableDepth; - indexToBeCopyed = indexToBeCopyed + 1; - } - else - { - indexToBeCopyed = 0; + for (int indexToBeCopyed = 0; indexToBeCopyed < 366; indexToBeCopyed++) + { + if (dailyPredictions[indexToBeCopyed].date.month == myDate.month() && dailyPredictions[indexToBeCopyed].date.day == myDate.day()) + { + dailyPredictions[index].waterTableDepth = dailyPredictions[indexToBeCopyed].waterTableDepth; + } + } + } index = index + 1; } From b6918a684e8b6079f5f6ecd43d15d4d7abcd2145 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 5 Jun 2024 11:59:55 +0200 Subject: [PATCH 048/179] fix firstDate and startDate to copy data --- weatherGenerator/weatherGenerator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 44acf908..439c16bd 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1038,8 +1038,8 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS int fixWgDoy1 = wgDoy1; int fixWgDoy2 = wgDoy2; int index = 0; - QDate firstDate(myPredictionYear,1,1); - QDate lastDate(lastYear,12,31); + QDate firstDate(dailyPredictions[0].date.year, dailyPredictions[0].date.month, dailyPredictions[0].date.day); + QDate lastDate = firstDate.addDays(nrValues); for (QDate myDate = firstDate; myDate <= lastDate; myDate=myDate.addDays(1)) { @@ -1048,9 +1048,10 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS { for (int indexToBeCopyed = 0; indexToBeCopyed < 366; indexToBeCopyed++) { - if (dailyPredictions[indexToBeCopyed].date.month == myDate.month() && dailyPredictions[indexToBeCopyed].date.day == myDate.day()) + if (dailyPredictions[indexToBeCopyed].date.month == myDate.month() && dailyPredictions[indexToBeCopyed].date.day == myDate.day() && dailyPredictions[indexToBeCopyed].waterTableDepth != NODATA) { dailyPredictions[index].waterTableDepth = dailyPredictions[indexToBeCopyed].waterTableDepth; + break; } } From ead95c8240837da58ea5a40702e98cf4cff06e96 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Wed, 5 Jun 2024 15:48:09 +0200 Subject: [PATCH 049/179] remove = in final loop --- weatherGenerator/weatherGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 439c16bd..8d42e476 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1041,7 +1041,7 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS QDate firstDate(dailyPredictions[0].date.year, dailyPredictions[0].date.month, dailyPredictions[0].date.day); QDate lastDate = firstDate.addDays(nrValues); - for (QDate myDate = firstDate; myDate <= lastDate; myDate=myDate.addDays(1)) + for (QDate myDate = firstDate; myDate < lastDate; myDate=myDate.addDays(1)) { setCorrectWgDoy(wgDoy1, wgDoy2, myPredictionYear, myDate.year(), fixWgDoy1, fixWgDoy2); if ( !isWGDate(Crit3DDate(myDate.day(), myDate.month(), myDate.year()), fixWgDoy1, fixWgDoy2) && dailyPredictions[index].waterTableDepth == NODATA) From 62959ea349bcc9c6f8dc9315c6d20f822cca8d33 Mon Sep 17 00:00:00 2001 From: Fausto Tomei Date: Wed, 5 Jun 2024 15:48:46 +0200 Subject: [PATCH 050/179] update info --- weatherGenerator/weatherGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 439c16bd..8fb225bb 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -805,7 +805,7 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno /*! * \name makeSeasonalForecastWaterTable - * \brief Generates a time series of daily data (Tmin, Tmax, Prec, Depth) + * \brief Generates a time series of daily data (Tmin, Tmax, Prec, Water table depth) * for a period of nrYears = numMembers * nrRepetitions * Different members of anomalies loaded by xml files are added to the climate * Output is written on outputFileName (csv) From 709f2c3f42369e05e5ebddc41ade0d5013d01f5a Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 5 Jun 2024 18:59:57 +0200 Subject: [PATCH 051/179] fix watertable --- crit3dDate/crit3dDate.cpp | 25 +-- waterTable/waterTable.cpp | 63 +++++--- waterTable/waterTable.h | 15 +- weatherGenerator/timeUtility.h | 1 + weatherGenerator/weatherGenerator.cpp | 224 ++++++++++++++------------ weatherGenerator/weatherGenerator.h | 8 +- 6 files changed, 184 insertions(+), 152 deletions(-) diff --git a/crit3dDate/crit3dDate.cpp b/crit3dDate/crit3dDate.cpp index dc112ca8..09b83f14 100644 --- a/crit3dDate/crit3dDate.cpp +++ b/crit3dDate/crit3dDate.cpp @@ -208,31 +208,10 @@ Crit3DDate min(const Crit3DDate& myDate1, const Crit3DDate& myDate2) Crit3DDate getDateFromDoy(int year, int doy) { - if (doy < 1) return NO_DATE; - short month; - - // before 29 february - if (doy <= 59) - { - month = (doy <= 31) ? 1 : 2; - return Crit3DDate(doy-doyMonth[month-1], month, year); - } - - const short leap = isLeapYear(year) ? 1 : 0; - if (doy > (365 + leap)) return NO_DATE; - - // 29 february - if (doy == 60 && leap == 1) - return Crit3DDate(29, 2, year); - - // after - month = 3; - while (month <= 12 && doy > (doyMonth[month]+leap)) - month++; - - return Crit3DDate(doy-(doyMonth[month-1]+leap), month, year); + return Crit3DDate(1, 1, year).addDays(doy-1); } + void Crit3DDate::setNullDate() { day = 0; diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index c2c79c06..66f0e6ce 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -51,9 +51,12 @@ void WaterTable::cleanAllMeteoVector() { inputTMin.clear(); inputTMax.clear(); - inputPrec.clear();; - etpValues.clear();; - precValues.clear();; + inputPrec.clear(); + etpValues.clear(); + precValues.clear(); + + firstMeteoDate = QDate(); + lastMeteoDate = QDate(); } @@ -74,9 +77,13 @@ std::vector WaterTable::getMyInterpolateSeries() void WaterTable::initializeWaterTable(Well myWell) { - this->well = myWell; + well = myWell; + + gis::getLatLonFromUtm(gisSettings, well.getUtmX(), well.getUtmY(), &lat, &lon); + getFirstDateWell(); getLastDateWell(); + for (int myMonthIndex = 0; myMonthIndex < 12; myMonthIndex++) { WTClimateMonthly[myMonthIndex] = NODATA; @@ -108,7 +115,7 @@ bool WaterTable::computeWaterTableParameters(Well myWell, int maxNrDays) initializeWaterTable(myWell); isClimateReady = computeWTClimate(); - if (! computeETP_allSeries()) + if (! computeETP_allSeries(true)) { return false; } @@ -167,12 +174,28 @@ bool WaterTable::computeWTClimate() } -bool WaterTable::computeETP_allSeries() +bool WaterTable::setMeteoData(QDate myDate, float tmin, float tmax, float prec) +{ + int index = firstMeteoDate.daysTo(myDate); + + if (index < etpValues.size() && index < precValues.size()) + { + Crit3DDate date = Crit3DDate(myDate.day(), myDate.month(), myDate.year()); + etpValues[index] = dailyEtpHargreaves(tmin, tmax, date, lat, &meteoSettings); + precValues[index] = prec; + return true; + } + else + { + return false; + } +} + + +bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) { etpValues.clear(); precValues.clear(); - double myLat, myLon; - gis::getLatLonFromUtm(gisSettings, well.getUtmX(), well.getUtmY(), &myLat, &myLon); float sumCWB = 0; int nrValidDays = 0; @@ -181,7 +204,8 @@ bool WaterTable::computeETP_allSeries() float Tmax = NODATA; float prec = NODATA; float etp = NODATA; - for (QDate myDate = firstMeteoDate; myDate<=lastMeteoDate; myDate=myDate.addDays(1)) + + for (QDate myDate = firstMeteoDate; myDate <= lastMeteoDate; myDate = myDate.addDays(1)) { Crit3DDate date(myDate.day(), myDate.month(), myDate.year()); if (index > inputTMin.size() || index > inputTMax.size() || index > inputPrec.size()) @@ -197,7 +221,7 @@ bool WaterTable::computeETP_allSeries() Tmin = inputTMin[index]; Tmax = inputTMax[index]; prec = inputPrec[index]; - etp = dailyEtpHargreaves(Tmin, Tmax, date, myLat,&meteoSettings); + etp = dailyEtpHargreaves(Tmin, Tmax, date, lat, &meteoSettings); } etpValues.push_back(etp); precValues.push_back(prec); @@ -209,14 +233,17 @@ bool WaterTable::computeETP_allSeries() index = index + 1; } - if (nrValidDays > 0) - { - avgDailyCWB = sumCWB / nrValidDays; - } - else + if (isUpdateAvgCWB) { - error = "Missing data"; - return false; + if (nrValidDays > 0) + { + avgDailyCWB = sumCWB / nrValidDays; + } + else + { + error = "Missing data"; + return false; + } } return true; @@ -414,9 +441,9 @@ float WaterTable::getWaterTableDaily(QDate myDate) return getWaterTableDaily; } + float WaterTable::getWaterTableClimate(QDate myDate) { - float getWaterTableClimate = NODATA; if (!isClimateReady) diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 10210eb1..5f225fb4 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -26,7 +26,7 @@ class WaterTable void initializeWaterTable(Well myWell); bool computeWaterTableParameters(Well myWell, int maxNrDays); bool computeWTClimate(); - bool computeETP_allSeries(); + bool computeETP_allSeries(bool isUpdateAvgCWB); bool computeCWBCorrelation(int maxNrDays); double computeCWB(QDate myDate, int nrDays); bool computeWaterTableIndices(); @@ -35,6 +35,7 @@ class WaterTable bool computeWaterTableClimate(QDate currentDate, int yearFrom, int yearTo, float* myValue); bool getWaterTableInterpolation(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays); void computeWaterTableSeries(); + bool setMeteoData(QDate myDate, float tmin, float tmax, float prec); QString getError() const { return error; } @@ -61,6 +62,16 @@ class WaterTable void setInputPrec(const std::vector &newInputPrec); + void setFirstMeteoDate(QDate myDate) + { + firstMeteoDate = myDate; + } + + void setLastMeteoDate(QDate myDate) + { + lastMeteoDate = myDate; + } + private: Crit3DMeteoSettings meteoSettings; gis::Crit3DGisSettings gisSettings; @@ -77,6 +88,8 @@ class WaterTable std::vector etpValues; std::vector precValues; + double lat, lon; + int nrDaysPeriod; double alpha; double h0; diff --git a/weatherGenerator/timeUtility.h b/weatherGenerator/timeUtility.h index aa63fa05..88a3d9d0 100644 --- a/weatherGenerator/timeUtility.h +++ b/weatherGenerator/timeUtility.h @@ -6,6 +6,7 @@ class Crit3DDate; class QString; + class QDate; int getMonthsInPeriod(int month1, int month2); diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 622413c6..6ea3d8df 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -803,72 +803,119 @@ bool makeSeasonalForecast(QString outputFileName, char separator, XMLSeasonalAno return true; } + +bool initializeWaterTableData(TinputObsData* dailyObsData, WaterTable *waterTable, + int predictionYear, int wgDoy1, int nrDaysBeforeWgDoy1, int daysWg) +{ + Crit3DDate seasonFirstDate = getDateFromDoy(predictionYear, wgDoy1); + Crit3DDate outputFirstDate = seasonFirstDate.addDays(-nrDaysBeforeWgDoy1); + + int firstIndex = difference(dailyObsData->inputFirstDate, outputFirstDate); + int totDays = firstIndex + nrDaysBeforeWgDoy1 + daysWg; + + std::vector inputTMin, inputTMax, inputPrec; + for (int i = 0; i < totDays; i++) + { + if (i < (firstIndex + nrDaysBeforeWgDoy1)) + { + inputTMin.push_back(dailyObsData->inputTMin[i]); + inputTMax.push_back(dailyObsData->inputTMax[i]); + inputPrec.push_back(dailyObsData->inputPrecip[i]); + } + else + { + // aggiungo giorni (vuoti) a watertable + inputTMin.push_back(NODATA); + inputTMax.push_back(NODATA); + inputPrec.push_back(NODATA); + } + } + + waterTable->setInputTMin(inputTMin); + waterTable->setInputTMax(inputTMax); + waterTable->setInputPrec(inputPrec); + + QDate firstDate = QDate(dailyObsData->inputFirstDate.year, dailyObsData->inputFirstDate.month, dailyObsData->inputFirstDate.day); + QDate lastDate = firstDate.addDays(totDays-1); + + waterTable->setFirstMeteoDate(firstDate); + waterTable->setLastMeteoDate(lastDate); + + waterTable->computeETP_allSeries(false); + + return true; +} + + /*! * \name makeSeasonalForecastWaterTable - * \brief Generates a time series of daily data (Tmin, Tmax, Prec, Water table depth) + * \brief Generates a time series of daily data (Tmin, Tmax, Prec, WaterTable depth) * for a period of nrYears = numMembers * nrRepetitions * Different members of anomalies loaded by xml files are added to the climate * Output is written on outputFileName (csv) */ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, - TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, - int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, - float rainfallThreshold, WaterTable waterTable) + TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, WaterTable *waterTable, + int nrRepetitions, int predictionYear, int wgDoy1, int wgDoy2, + float rainfallThreshold) { - TweatherGenClimate wGen; - std::vector dailyPredictions; - - Crit3DDate myFirstDatePrediction, seasonFirstDate, seasonLastDate; - - unsigned int nrMembers; // number of models into xml anomaly file - unsigned int nrYears; // number of years of the output series. It is the length of the virtual period where all the previsions (one for each model) are given one after another - unsigned int nrValues; // number of days between the first and the last prediction year - int firstYear, lastYear, myYear; - unsigned int obsIndex; - unsigned int addday = 0; - bool isLastMember = false; - // it checks if observed data includes the last 9 months before wgDoy1 int nrDaysBeforeWgDoy1; if (! checkLastYearDate(dailyObsData->inputFirstDate, dailyObsData->inputLastDate, - dailyObsData->dataLength, myPredictionYear, wgDoy1, nrDaysBeforeWgDoy1)) + dailyObsData->dataLength, predictionYear, wgDoy1, nrDaysBeforeWgDoy1)) { qDebug() << "ERROR: observed data should include at least 9 months before wgDoy1"; return false; } - nrMembers = 0; - for (int i = 0; imodelMember.size(); i++) - { - nrMembers += XMLAnomaly->modelMember[i].toUInt(); - } - - nrYears = nrMembers * unsigned(nrRepetitions); - - firstYear = myPredictionYear; - - // wgDoy1 within myPredictionYear, wgDoy2 within myPredictionYear+1 - if (wgDoy1 < wgDoy2) - lastYear = firstYear + signed(nrYears) - 1; - else - lastYear = firstYear + signed(nrYears); - - seasonFirstDate = getDateFromDoy (myPredictionYear, wgDoy1); + Crit3DDate seasonLastDate; int daysWg; + Crit3DDate seasonFirstDate = getDateFromDoy (predictionYear, wgDoy1); if (wgDoy1 < wgDoy2) { - seasonLastDate = getDateFromDoy (myPredictionYear, wgDoy2); + seasonLastDate = getDateFromDoy (predictionYear, wgDoy2); daysWg = wgDoy2 - wgDoy1 + 1; } else { - seasonLastDate = getDateFromDoy (myPredictionYear+1, wgDoy2); - daysWg = wgDoy1 - wgDoy2 + 1; + seasonLastDate = getDateFromDoy (predictionYear+1, wgDoy2); + if (isLeapYear(predictionYear)) + { + daysWg = (366 - wgDoy1) + wgDoy2 + 1; + } + else + { + daysWg = (365 - wgDoy1) + wgDoy2 + 1; + } } - myFirstDatePrediction = seasonFirstDate.addDays(-nrDaysBeforeWgDoy1); + if (! initializeWaterTableData(dailyObsData, waterTable, predictionYear, wgDoy1, nrDaysBeforeWgDoy1, daysWg)) + { + qDebug() << "ERROR in initializeWaterTableData"; + return false; + } - for (int i = myPredictionYear; i <= lastYear; i++) + TweatherGenClimate wGen; + std::vector dailyPredictions; + + unsigned int nrMembers; // number of models into xml anomaly file + unsigned int nrYears; // number of years of the output series. It is the length of the virtual period where all the previsions (one for each model) are given one after another + unsigned int nrValues; // number of days between the first and the last prediction year + + nrMembers = 0; + for (int i = 0; imodelMember.size(); i++) + { + nrMembers += XMLAnomaly->modelMember[i].toUInt(); + } + + nrYears = nrMembers * unsigned(nrRepetitions); + int lastYear = predictionYear + signed(nrYears) - 1; + if (wgDoy2 < wgDoy1) lastYear++; + + Crit3DDate firstDatePrediction = seasonFirstDate.addDays(-nrDaysBeforeWgDoy1); + + unsigned int addday = 0; + for (int i = predictionYear; i <= lastYear; i++) { if (isLeapYear(i)) addday++; @@ -883,51 +930,24 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS dailyPredictions.resize(nrValues); - // copy the last 9 months before wgDoy1 float lastTmax = NODATA; float lastTmin = NODATA; - // copy values to waterTable - std::vector inputTMin; - std::vector inputTMax; - std::vector inputPrec; - obsIndex = difference(dailyObsData->inputFirstDate, myFirstDatePrediction); - int totDays = nrDaysBeforeWgDoy1 + daysWg; - for (int i = 0; i < totDays; i++) - { - if (i < nrDaysBeforeWgDoy1) - { - inputTMin.push_back(dailyObsData->inputTMin[obsIndex+i]); - inputTMax.push_back(dailyObsData->inputTMax[obsIndex+i]); - inputPrec.push_back(dailyObsData->inputPrecip[obsIndex+i]); - } - else - { - // in base a wgdoy1 e wgdoy2 aggiungo giorni (vuoti) a watertable - inputTMin.push_back(NODATA); - inputTMax.push_back(NODATA); - inputPrec.push_back(NODATA); - } - } - waterTable.setInputTMin(inputTMin); - waterTable.setInputTMax(inputTMax); - waterTable.setInputPrec(inputPrec); - waterTable.computeETP_allSeries(); - float myDepth; + float wtDepth; float myDelta; int myDeltaDays; - Crit3DDate myDate = myFirstDatePrediction; + Crit3DDate myDate = firstDatePrediction; for (int tmp = 0; tmp < nrDaysBeforeWgDoy1; tmp++) { dailyPredictions[tmp].date = myDate; - obsIndex = difference(dailyObsData->inputFirstDate, dailyPredictions[tmp].date); + int obsIndex = difference(dailyObsData->inputFirstDate, dailyPredictions[tmp].date); dailyPredictions[tmp].minTemp = dailyObsData->inputTMin[obsIndex]; dailyPredictions[tmp].maxTemp = dailyObsData->inputTMax[obsIndex]; dailyPredictions[tmp].prec = dailyObsData->inputPrecip[obsIndex]; - if (waterTable.getWaterTableInterpolation(QDate(myDate.year, myDate.month, myDate.day), &myDepth, &myDelta, &myDeltaDays)) + if (waterTable->getWaterTableInterpolation(QDate(myDate.year, myDate.month, myDate.day), &wtDepth, &myDelta, &myDeltaDays)) { - dailyPredictions[tmp].waterTableDepth = myDepth; + dailyPredictions[tmp].waterTableDepth = wtDepth; } if ((int(dailyPredictions[tmp].maxTemp) == int(NODATA)) @@ -965,17 +985,16 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS // store the climate without anomalies wGen = wGenClimate; - myYear = firstYear; + int myYear = predictionYear; + bool isLastMember = false; - // first month of my season int anomalyMonth1 = seasonFirstDate.month; - // last month of my season int anomalyMonth2 = seasonLastDate.month; for (unsigned int modelIndex = 0; modelIndex < nrMembers; modelIndex++) { // assign anomaly - if ( !assignXMLAnomaly(XMLAnomaly, modelIndex, anomalyMonth1, anomalyMonth2, wGenClimate, wGen)) + if (! assignXMLAnomaly(XMLAnomaly, modelIndex, anomalyMonth1, anomalyMonth2, wGenClimate, wGen)) { qDebug() << "Error in Scenario: assignXMLAnomaly returns false"; return false; @@ -988,7 +1007,7 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS // compute seasonal prediction std::vector indexWg; if (! computeSeasonalPredictions(dailyObsData, wGen, - myPredictionYear, myYear, nrRepetitions, + predictionYear, myYear, nrRepetitions, wgDoy1, wgDoy2, rainfallThreshold, isLastMember, dailyPredictions, &outputDataLength, indexWg)) { @@ -998,31 +1017,19 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS if (indexWg.size() != 0) { - //qDebug() << "indexWg[0] " << indexWg[0]; - //qDebug() << "indexWg [indexWg.size()-1] " << indexWg [indexWg.size()-1]; - //int nWgDays = indexWg [indexWg.size()-1] - indexWg[0]; - //qDebug() << "nWgDays " << nWgDays; - for (int tmp = 0; tmp < daysWg; tmp++) - { - inputTMin[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[indexWg[0]+tmp].minTemp; - inputTMax[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[indexWg[0]+tmp].maxTemp; - inputPrec[nrDaysBeforeWgDoy1 + tmp] = dailyPredictions[indexWg[0]+tmp].prec; - } - // calcola etp - waterTable.cleanAllMeteoVector(); - waterTable.setInputTMin(inputTMin); - waterTable.setInputTMax(inputTMax); - waterTable.setInputPrec(inputPrec); - waterTable.computeETP_allSeries(); - float myDepth; - float myDelta; - int myDeltaDays; QDate myDate(seasonFirstDate.year, seasonFirstDate.month, seasonFirstDate.day); - for (int tmp = 0; tmp < daysWg; tmp++) + for (int i = 0; i < daysWg; i++) { - if (waterTable.getWaterTableInterpolation(myDate, &myDepth, &myDelta, &myDeltaDays)) + int currentIndex = indexWg[0] + i; + float tmin = dailyPredictions[currentIndex].minTemp; + float tmax = dailyPredictions[currentIndex].maxTemp; + float prec = dailyPredictions[currentIndex].prec; + if (waterTable->setMeteoData(myDate, tmin, tmax, prec)) { - dailyPredictions[indexWg[0]+tmp].waterTableDepth = myDepth; + if (waterTable->getWaterTableInterpolation(myDate, &wtDepth, &myDelta, &myDeltaDays)) + { + dailyPredictions[currentIndex].waterTableDepth = wtDepth; + } } myDate = myDate.addDays(1); } @@ -1031,8 +1038,8 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS // next model myYear = myYear + nrRepetitions; } - qDebug() << "\n>>> output:" << outputFileName; + qDebug() << "\n>>> output:" << outputFileName; // copy all waterTableDepth outside wg period int fixWgDoy1 = wgDoy1; @@ -1043,8 +1050,9 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS for (QDate myDate = firstDate; myDate < lastDate; myDate=myDate.addDays(1)) { - setCorrectWgDoy(wgDoy1, wgDoy2, myPredictionYear, myDate.year(), fixWgDoy1, fixWgDoy2); - if ( !isWGDate(Crit3DDate(myDate.day(), myDate.month(), myDate.year()), fixWgDoy1, fixWgDoy2) && dailyPredictions[index].waterTableDepth == NODATA) + setCorrectWgDoy(wgDoy1, wgDoy2, predictionYear, myDate.year(), fixWgDoy1, fixWgDoy2); + if (! isWGDate(Crit3DDate(myDate.day(), myDate.month(), myDate.year()), fixWgDoy1, fixWgDoy2) + && dailyPredictions[index].waterTableDepth == NODATA) { for (int indexToBeCopyed = 0; indexToBeCopyed < 366; indexToBeCopyed++) { @@ -1056,7 +1064,7 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS } } - index = index + 1; + index++; } writeMeteoDataCsv (outputFileName, separator, dailyPredictions, true); @@ -1090,8 +1098,6 @@ bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate int fixWgDoy1 = wgDoy1; int fixWgDoy2 = wgDoy2; - // TODO etp e falda - currentIndex = *outputDataLength; firstDate = outputDailyData[currentIndex-1].date.addDays(1); @@ -1103,13 +1109,15 @@ bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate if (isLastMember) { if ( (!isLeapYear(predictionYear) && !isLeapYear(lastYear)) || (isLeapYear(predictionYear) && isLeapYear(lastYear))) + { lastDate = getDateFromDoy(lastYear,wgDoy2); + } else { if(isLeapYear(predictionYear) && wgDoy2 >= 60 ) - lastDate = getDateFromDoy(lastYear,wgDoy2-1); + lastDate = getDateFromDoy(lastYear, wgDoy2-1); if(isLeapYear(lastYear) && wgDoy2 >= 59 ) - lastDate = getDateFromDoy(lastYear,wgDoy2+1); + lastDate = getDateFromDoy(lastYear, wgDoy2+1); } } else @@ -1125,7 +1133,9 @@ bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate if (isLastMember) { if ( (!isLeapYear(predictionYear+1) && !isLeapYear(lastYear)) || (isLeapYear(predictionYear+1) && isLeapYear(lastYear))) + { lastDate = getDateFromDoy(lastYear, wgDoy2); + } else { if(isLeapYear(predictionYear+1) && wgDoy2 >= 60) diff --git a/weatherGenerator/weatherGenerator.h b/weatherGenerator/weatherGenerator.h index 2994b8a0..50af3416 100644 --- a/weatherGenerator/weatherGenerator.h +++ b/weatherGenerator/weatherGenerator.h @@ -118,10 +118,12 @@ TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, int numRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, float rainfallThreshold); + bool initializeWaterTableData(TinputObsData* dailyObsData, WaterTable *waterTable, + int predictionYear, int wgDoy1, int nrDaysBeforeWgDoy1, int daysWg); + bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLSeasonalAnomaly* XMLAnomaly, - TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, - int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, - float rainfallThreshold, WaterTable waterTable); + TweatherGenClimate& wGenClimate, TinputObsData* dailyObsData, WaterTable *waterTable, + int nrRepetitions, int myPredictionYear, int wgDoy1, int wgDoy2, float rainfallThreshold); bool computeSeasonalPredictions(TinputObsData *dailyObsData, TweatherGenClimate& wgClimate, int predictionYear, int firstYear, int nrRepetitions, From 4ec3975b1ade8d6323b8c248904036e845e3cc23 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 5 Jun 2024 19:50:33 +0200 Subject: [PATCH 052/179] fix watertable lat --- waterTable/waterTable.cpp | 12 +++++------- waterTable/waterTable.h | 9 ++++----- waterTable/well.cpp | 37 ++++++++----------------------------- waterTable/well.h | 26 ++++++++++++++++++-------- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 66f0e6ce..1048b5b2 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -4,9 +4,9 @@ #include -WaterTable::WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, - Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings) - : inputTMin(inputTMin), inputTMax(inputTMax), inputPrec(inputPrec), firstMeteoDate(firstMeteoDate), lastMeteoDate(lastMeteoDate), meteoSettings(meteoSettings), gisSettings(gisSettings) +WaterTable::WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, + QDate firstMeteoDate, QDate lastMeteoDate, Crit3DMeteoSettings meteoSettings) + : inputTMin(inputTMin), inputTMax(inputTMax), inputPrec(inputPrec), firstMeteoDate(firstMeteoDate), lastMeteoDate(lastMeteoDate), meteoSettings(meteoSettings) { } @@ -79,8 +79,6 @@ void WaterTable::initializeWaterTable(Well myWell) { well = myWell; - gis::getLatLonFromUtm(gisSettings, well.getUtmX(), well.getUtmY(), &lat, &lon); - getFirstDateWell(); getLastDateWell(); @@ -181,7 +179,7 @@ bool WaterTable::setMeteoData(QDate myDate, float tmin, float tmax, float prec) if (index < etpValues.size() && index < precValues.size()) { Crit3DDate date = Crit3DDate(myDate.day(), myDate.month(), myDate.year()); - etpValues[index] = dailyEtpHargreaves(tmin, tmax, date, lat, &meteoSettings); + etpValues[index] = dailyEtpHargreaves(tmin, tmax, date, well.getLatitude(), &meteoSettings); precValues[index] = prec; return true; } @@ -221,7 +219,7 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) Tmin = inputTMin[index]; Tmax = inputTMax[index]; prec = inputPrec[index]; - etp = dailyEtpHargreaves(Tmin, Tmax, date, lat, &meteoSettings); + etp = dailyEtpHargreaves(Tmin, Tmax, date, well.getLatitude(), &meteoSettings); } etpValues.push_back(etp); precValues.push_back(prec); diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 5f225fb4..a23da6a7 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -18,8 +18,9 @@ class WaterTable { public: - WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, - Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings); + WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, + QDate firstMeteoDate, QDate lastMeteoDate, Crit3DMeteoSettings meteoSettings); + QString getIdWell() const; QDate getFirstDateWell(); QDate getLastDateWell(); @@ -74,7 +75,7 @@ class WaterTable private: Crit3DMeteoSettings meteoSettings; - gis::Crit3DGisSettings gisSettings; + QDate firstDateWell; QDate lastDateWell; QDate firstMeteoDate; @@ -88,8 +89,6 @@ class WaterTable std::vector etpValues; std::vector precValues; - double lat, lon; - int nrDaysPeriod; double alpha; double h0; diff --git a/waterTable/well.cpp b/waterTable/well.cpp index 9e6f3c11..be4b33c9 100644 --- a/waterTable/well.cpp +++ b/waterTable/well.cpp @@ -1,40 +1,18 @@ +#include "commonConstants.h" #include "well.h" #include Well::Well() { + lat = NODATA; + lon = NODATA; + utmX = NODATA; + utmY = NODATA; + id = ""; + depths.clear(); } -QString Well::getId() const -{ - return id; -} - -void Well::setId(const QString &newId) -{ - id = newId; -} - -double Well::getUtmX() const -{ - return utmX; -} - -void Well::setUtmX(double newUtmX) -{ - utmX = newUtmX; -} - -double Well::getUtmY() const -{ - return utmY; -} - -void Well::setUtmY(double newUtmY) -{ - utmY = newUtmY; -} void Well::insertData(QDate myDate, float myValue) { @@ -67,6 +45,7 @@ QDate Well::getFirstDate() return firstDate; } + QDate Well::getLastDate() { QList allDates = depths.keys(); diff --git a/waterTable/well.h b/waterTable/well.h index 57afd074..aeb72800 100644 --- a/waterTable/well.h +++ b/waterTable/well.h @@ -10,14 +10,21 @@ class Well { public: Well(); - QString getId() const; - void setId(const QString &newId); - double getUtmX() const; - void setUtmX(double newUtmX); + QString getId() const { return id; } + void setId(const QString &newId) { id = newId; } - double getUtmY() const; - void setUtmY(double newUtmY); + double getUtmX() const { return utmX; } + void setUtmX(double newUtmX) { utmX = newUtmX; } + + double getUtmY() const { return utmY; } + void setUtmY(double newUtmY) { utmY = newUtmY; } + + double getLatitude() const { return lat; } + void setLatitude(double newLat) { lat = newLat; } + + double getLongitude() const { return lon; } + void setLongitude(double newLon) { lon = newLon; } void insertData(QDate myDate, float myValue); @@ -32,9 +39,12 @@ class Well private: QString id; - double utmX; - double utmY; + + double utmX, utmY; + double lat, lon; + QMap depths; + QDate firstDate; QDate lastDate; }; From 1ce0f34e67a20fd995e8209f21519583650484f9 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 5 Jun 2024 20:24:35 +0200 Subject: [PATCH 053/179] update --- waterTable/importData.cpp | 4 ++-- waterTable/importData.h | 19 +++++++++++-------- waterTable/waterTable.cpp | 10 +++++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index b336a915..141f5fa2 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -204,7 +204,7 @@ bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellL return true; } -bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines) +bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) { QFile myFile(csvDepths); QList errorList; @@ -239,7 +239,7 @@ bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximu } items[posDate] = items[posDate].simplified(); QDate date = QDate::fromString(items[posDate].remove(QChar('"')),"yyyy-MM-dd"); - if (! date.isValid() || date < climateObsFirstDate || date > climateObsLastDate) + if (! date.isValid()) { errorList.append(line); wrongLines++; diff --git a/waterTable/importData.h b/waterTable/importData.h index 9b75c9c0..39f0ba49 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -1,14 +1,17 @@ #ifndef IMPORTDATA_H #define IMPORTDATA_H -#include -#ifndef WELL_H - #include "well.h" -#endif - -bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines); -bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); -bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QDate climateObsFirstDate, QDate climateObsLastDate, QString &errorStr, int &wrongLines); + #include + #ifndef WELL_H + #include "well.h" + #endif + + bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines); + + bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, + QString &errorStr, int &wrongLines); + + bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 1048b5b2..70573577 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -119,7 +119,7 @@ bool WaterTable::computeWaterTableParameters(Well myWell, int maxNrDays) } isCWBEquationReady = computeCWBCorrelation(maxNrDays); - if (!isCWBEquationReady) + if (! isCWBEquationReady) { return false; } @@ -225,7 +225,7 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) precValues.push_back(prec); if (etp != NODATA && prec != NODATA) { - sumCWB = sumCWB + (prec - etp); + sumCWB += prec - etp; nrValidDays = nrValidDays + 1; } index = index + 1; @@ -313,7 +313,7 @@ double WaterTable::computeCWB(QDate myDate, int nrDays) double sumCWB = 0; int nrValidDays = 0; QDate actualDate; - for (int shift = 1; shift<=nrDays; shift++) + for (int shift = 1; shift <= nrDays; shift++) { actualDate = myDate.addDays(-shift); int index = firstMeteoDate.daysTo(actualDate); @@ -324,9 +324,9 @@ double WaterTable::computeCWB(QDate myDate, int nrDays) if ( etp != NODATA && prec != NODATA) { double currentCWB = double(prec - etp); - double weight = 1 - (double)shift/nrDays; + double weight = 1 - double(shift-1) / double(nrDays); sumCWB += currentCWB * weight; - nrValidDays = nrValidDays + 1; + nrValidDays++; } } } From 96bb00a6d3449ca589621233bc67368f0aa5ca5d Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 5 Jun 2024 20:29:09 +0200 Subject: [PATCH 054/179] update --- waterTable/waterTable.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 70573577..3408d4ed 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -258,16 +258,16 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) QMap myDepths = well.getObsDepths(); std::vector myCWBSum; std::vector myObsWT; - float a; - float b; - float myR2; + float a, b; + float currentR2; maxNrDays = std::max(90, maxNrDays); - for (int nrDays = 90; nrDays <= maxNrDays; nrDays = nrDays+5) + for (int nrDays = 90; nrDays <= maxNrDays; nrDays += 5) { myCWBSum.clear(); myObsWT.clear(); QMapIterator it(myDepths); + while (it.hasNext()) { it.next(); @@ -281,10 +281,10 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) } } - statistics::linearRegression(myCWBSum, myObsWT, int(myCWBSum.size()), false, &a, &b, &myR2); - if (myR2 > bestR2) + statistics::linearRegression(myCWBSum, myObsWT, int(myCWBSum.size()), false, &a, &b, ¤tR2); + if (currentR2 > bestR2) { - bestR2 = myR2; + bestR2 = currentR2; bestNrDays = nrDays; bestH0 = a; bestAlfaCoeff = b; From fa47fc449d542189a6fb665cabba8d1c4231a5f7 Mon Sep 17 00:00:00 2001 From: lauracosta Date: Thu, 6 Jun 2024 14:15:16 +0200 Subject: [PATCH 055/179] fix indexWg loop --- weatherGenerator/weatherGenerator.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 6ea3d8df..829ba03a 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1014,13 +1014,11 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS qDebug() << "Error in computeSeasonalPredictions"; return false; } - if (indexWg.size() != 0) { QDate myDate(seasonFirstDate.year, seasonFirstDate.month, seasonFirstDate.day); - for (int i = 0; i < daysWg; i++) + for (int currentIndex = indexWg[0]; currentIndex <= indexWg[indexWg.size()-1]; currentIndex++) { - int currentIndex = indexWg[0] + i; float tmin = dailyPredictions[currentIndex].minTemp; float tmax = dailyPredictions[currentIndex].maxTemp; float prec = dailyPredictions[currentIndex].prec; @@ -1034,7 +1032,6 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS myDate = myDate.addDays(1); } } - // next model myYear = myYear + nrRepetitions; } From 842cb07da62d6d6ca05ff89c56be21b4b2b6d960 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 14:28:11 +0200 Subject: [PATCH 056/179] export ensemble grid --- dbMeteoGrid/dbMeteoGrid.cpp | 3 +- dbMeteoGrid/dbMeteoGrid.h | 2 +- project/project.cpp | 4 +- project/shell.cpp | 11 +-- waterTable/importData.cpp | 129 +++++++++++++++++++----------------- waterTable/importData.h | 6 +- 6 files changed, 86 insertions(+), 69 deletions(-) diff --git a/dbMeteoGrid/dbMeteoGrid.cpp b/dbMeteoGrid/dbMeteoGrid.cpp index 602b34b5..c8b550dd 100644 --- a/dbMeteoGrid/dbMeteoGrid.cpp +++ b/dbMeteoGrid/dbMeteoGrid.cpp @@ -3936,7 +3936,8 @@ bool Crit3DMeteoGridDbHandler::saveLogProcedures(QString *myError, QString nameP * \return true on success, false otherwise */ bool Crit3DMeteoGridDbHandler::exportDailyDataCsv(QString &errorStr, QList variableList, - QDate firstDate, QDate lastDate, QString idListFileName, QString outputPath) + QDate firstDate, QDate lastDate, QString idListFileName, + QString outputPath, bool isEnsemble) { errorStr = ""; diff --git a/dbMeteoGrid/dbMeteoGrid.h b/dbMeteoGrid/dbMeteoGrid.h index 0d72ea8c..11f750e6 100644 --- a/dbMeteoGrid/dbMeteoGrid.h +++ b/dbMeteoGrid/dbMeteoGrid.h @@ -162,7 +162,7 @@ bool setActiveStateCellsInList(QString *myError, QList idList, bool activeState); bool exportDailyDataCsv(QString &errorStr, QList variableList, - QDate firstDate, QDate lastDate, QString idListFileName, QString outputPath); + QDate firstDate, QDate lastDate, QString idListFileName, QString outputPath, bool isEnsemble); bool MeteoGridToRasterFlt(double cellSize, const gis::Crit3DGisSettings &gisSettings, gis::Crit3DRasterGrid& myGrid); QDate getFirstDailyDate() const; diff --git a/project/project.cpp b/project/project.cpp index ffc9e43f..7d97368f 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4619,7 +4619,7 @@ bool Project::waterTableImportLocation(const QString &csvFileName) } int wrongLines = 0; - if (! loadWaterTableLocationCsv(csvFileName, wellPoints, errorString, wrongLines)) + if (! loadWaterTableLocationCsv(csvFileName, wellPoints, gisSettings, errorString, wrongLines)) { logError(errorString); return false; @@ -4714,7 +4714,7 @@ bool Project::computeSingleWell(int indexWell) QDate firstDate(linkedMeteoPoint.getFirstDailyData().year, linkedMeteoPoint.getFirstDailyData().month, linkedMeteoPoint.getFirstDailyData().day); QDate lastDate(linkedMeteoPoint.getLastDailyData().year, linkedMeteoPoint.getLastDailyData().month, linkedMeteoPoint.getLastDailyData().day); - WaterTable waterTable(inputTMin, inputTMax, inputPrec, firstDate, lastDate, *meteoSettings, gisSettings); + WaterTable waterTable(inputTMin, inputTMax, inputPrec, firstDate, lastDate, *meteoSettings); waterTable.computeWaterTableParameters(wellPoints[indexWell], maxNrDays); waterTable.computeWaterTableSeries(); // prepare series to show diff --git a/project/shell.cpp b/project/shell.cpp index c2be7f5d..08c93e18 100644 --- a/project/shell.cpp +++ b/project/shell.cpp @@ -288,7 +288,7 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) "ExportDailyDataCsv -v:variableList [-TPREC] [-t:type] -d1:firstDate [-d2:lastDate] [-l:idList] [-p:outputPath]\n" "-v list of comma separated variables (varname: TMIN, TMAX, TAVG, PREC, RHMIN, RHMAX, RHAVG, RAD, ET0_HS, ET0_PM, LEAFW) \n" "-TPREC export Tmin, Tmax, Tavg, Prec \n" - "-t type: GRID|POINTS (default: GRID) \n" + "-t type: GRID|ENSEMBLE_GRID|POINTS (default: GRID) \n" "-d1, -d2 date format: YYYY-MM-DD (default: lastDate = yesterday) \n" "-l list of output points or cells filename (default: ALL active cells/points) \n" "-p output Path (default: " + outputPath + ") \n"; @@ -359,9 +359,9 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) { typeStr = argumentList[i].right(argumentList[i].length()-3).toUpper(); - if (typeStr != "GRID" && typeStr != "POINTS") + if (typeStr != "GRID" && typeStr != "POINTS" && typeStr != "ENSEMBLE_GRID") { - myProject->logError("Wrong type: available GRID or POINTS."); + myProject->logError("Wrong type: available GRID or ENSEMBLE_GRID or POINTS."); return PRAGA_OK; } } @@ -423,7 +423,7 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) myProject->logInfo("... output path is: " + outputPath); - if (typeStr == "GRID") + if (typeStr == "GRID" || typeStr == "ENSEMBLE_GRID") { if (! myProject->meteoGridLoaded) { @@ -431,8 +431,9 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) return PRAGA_ERROR; } + bool isEnsemble = (typeStr == "ENSEMBLE_GRID"); if (! myProject->meteoGridDbHandler->exportDailyDataCsv(myProject->errorString, variableList, - firstDate, lastDate, idListFileName, outputPath)) + firstDate, lastDate, idListFileName, outputPath, isEnsemble)) { myProject->logError(); return PRAGA_ERROR; diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index 141f5fa2..e543eb48 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -4,87 +4,97 @@ #include #include #include "well.h" +#include "gis.h" -bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines) +bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, + const gis::Crit3DGisSettings& gisSettings, QString &errorStr, int &wrongLines) { - errorStr = ""; wellList.clear(); QFile myFile(csvFileName); + if (! myFile.open(QFile::ReadOnly | QFile::Text) ) + { + errorStr = "Csv file does not exist:\n" + csvFileName; + return false; + } + + QTextStream in(&myFile); + int nrRequiredFields = 3; + + // check header + QString line = in.readLine(); + QList headerItems = line.split(","); + if (headerItems.size() != nrRequiredFields) + { + errorStr = "Wrong data! Required well ID, utm X, utm Y."; + return false; + } + errorStr = ""; + QList idList; QList errorList; int posId = 0; int posUtmx = 1; int posUtmy = 2; - int nrRequiredFields = 3; int validLines = 0; - bool ok; - if (! myFile.open(QFile::ReadOnly | QFile::Text) ) - { - errorStr = "Csv file does not exist:\n" + csvFileName; - return false; - } - else + while (! in.atEnd()) { - QTextStream in(&myFile); + line = in.readLine(); + QList items = line.split(","); + items.removeAll({}); + if (items.size() < nrRequiredFields) + { + errorList.append(items[posId]); + wrongLines++; + continue; + } - // check header - QString line = in.readLine(); - QList headerItems = line.split(","); - if (headerItems.size() != nrRequiredFields) + items[posId] = items[posId].simplified(); + QString id = items[posId].remove(QChar('"')); + if (idList.contains(id)) { - errorStr = "Wrong data! Required well ID, utm X, utm Y."; - return false; + // id already saved + errorList.append(id); + wrongLines++; + continue; } + idList.append(id); - while (! in.atEnd()) + bool isOk; + items[posUtmx] = items[posUtmx].simplified(); + double utmX = items[posUtmx].remove(QChar('"')).toDouble(&isOk); + if (! isOk) { - line = in.readLine(); - QList items = line.split(","); - items.removeAll({}); - if (items.size() < nrRequiredFields) - { - errorList.append(items[posId]); - wrongLines++; - continue; - } - items[posId] = items[posId].simplified(); - QString id = items[posId].remove(QChar('"')); - if (idList.contains(id)) - { - // id already saved - errorList.append(id); - wrongLines++; - continue; - } - idList.append(id); - items[posUtmx] = items[posUtmx].simplified(); - double utmX = items[posUtmx].remove(QChar('"')).toDouble(&ok); - if (!ok) - { - errorList.append(id); - wrongLines++; - continue; - } - items[posUtmy] = items[posUtmy].simplified(); - double utmY = items[posUtmy].remove(QChar('"')).toDouble(&ok); - if (!ok) - { - errorList.append(id); - wrongLines++; - continue; - } + errorList.append(id); + wrongLines++; + continue; + } - Well newWell; - newWell.setId(id); - newWell.setUtmX(utmX); - newWell.setUtmY(utmY); - wellList.push_back(newWell); - validLines++; + items[posUtmy] = items[posUtmy].simplified(); + double utmY = items[posUtmy].remove(QChar('"')).toDouble(&isOk); + if (! isOk) + { + errorList.append(id); + wrongLines++; + continue; } + + double lat, lon; + gis::getLatLonFromUtm(gisSettings, utmX, utmY, &lat, &lon); + + Well newWell; + newWell.setId(id); + newWell.setUtmX(utmX); + newWell.setUtmY(utmY); + newWell.setLatitude(lat); + newWell.setLongitude(lon); + wellList.push_back(newWell); + + validLines++; } + myFile.close(); if (validLines == 0) @@ -204,6 +214,7 @@ bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellL return true; } + bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) { QFile myFile(csvDepths); diff --git a/waterTable/importData.h b/waterTable/importData.h index 39f0ba49..4c63bcbf 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -5,8 +5,12 @@ #ifndef WELL_H #include "well.h" #endif + #ifndef GIS_H + #include "gis.h" + #endif - bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, QString &errorStr, int &wrongLines); + bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &wellList, + const gis::Crit3DGisSettings &gisSettings, QString &errorStr, int &wrongLines); bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); From f5fffe5a52d38ff095ad25b55fa889677be2284f Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 14:31:01 +0200 Subject: [PATCH 057/179] update watertable --- waterTable/waterTable.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index a23da6a7..3e77410c 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -57,6 +57,7 @@ class WaterTable QMap getObsDepths(); void cleanAllMeteoVector(); + void setInputTMin(const std::vector &newInputTMin); void setInputTMax(const std::vector &newInputTMax); @@ -64,14 +65,10 @@ class WaterTable void setInputPrec(const std::vector &newInputPrec); void setFirstMeteoDate(QDate myDate) - { - firstMeteoDate = myDate; - } + { firstMeteoDate = myDate; } void setLastMeteoDate(QDate myDate) - { - lastMeteoDate = myDate; - } + { lastMeteoDate = myDate; } private: Crit3DMeteoSettings meteoSettings; From 020b4f8dfa50d016514761d453865266920d7fd2 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 15:05:53 +0200 Subject: [PATCH 058/179] update export daily --- dbMeteoGrid/dbMeteoGrid.cpp | 156 ++++++++++++++++++++++-------------- dbMeteoGrid/dbMeteoGrid.h | 8 +- project/shell.cpp | 13 ++- 3 files changed, 108 insertions(+), 69 deletions(-) diff --git a/dbMeteoGrid/dbMeteoGrid.cpp b/dbMeteoGrid/dbMeteoGrid.cpp index c8b550dd..b245a669 100644 --- a/dbMeteoGrid/dbMeteoGrid.cpp +++ b/dbMeteoGrid/dbMeteoGrid.cpp @@ -1894,14 +1894,14 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &myError, QStri myError = "Grid structure has not ensemble field"; return false; } + QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPoint + _tableDaily.postFix; QDate date; int varCode; float value; - unsigned row; - unsigned col; + unsigned row, col; if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { @@ -2535,6 +2535,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, return dailyVarList; } + std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, frequencyType freq, meteoVariable variable, QString id, QDateTime myFirstTime, QDateTime myLastTime, std::vector &dateStr) { QString myDateStr; @@ -3927,17 +3928,74 @@ bool Crit3DMeteoGridDbHandler::saveLogProcedures(QString *myError, QString nameP } + +bool Crit3DMeteoGridDbHandler::saveDailyDataCsv(const QString &csvFileName, const QList &variableList, + const QDate &firstDate, const QDate &lastDate, + unsigned row, unsigned col, QString &errorStr) +{ + // create csv file + QFile outputFile(csvFileName); + bool isOk = outputFile.open(QIODevice::WriteOnly | QFile::Truncate); + if (! isOk) + { + errorStr = "Open CSV failed: " + csvFileName; + return false; + } + + // write header + QTextStream outStream(&outputFile); + outStream << "Date"; + for (int i = 0; i < variableList.size(); i++) + { + if (variableList[i] != noMeteoVar) + { + std::string varName = getMeteoVarName(variableList[i]); + std::string unit = getUnitFromVariable(variableList[i]); + QString VarString = QString::fromStdString(varName + " (" + unit + ")"); + outStream << "," + VarString; + } + } + outStream << "\n"; + + // write data + QDate currentDate = firstDate; + while (currentDate <= lastDate) + { + outStream << currentDate.toString("yyyy-MM-dd"); + + for (int i = 0; i < variableList.size(); i++) + { + if (variableList[i] != noMeteoVar) + { + float value = _meteoGrid->meteoPointPointer(row, col)->getMeteoPointValueD(getCrit3DDate(currentDate), variableList[i]); + QString valueString = ""; + if (value != NODATA) + valueString = QString::number(value); + + outStream << "," << valueString; + } + } + outStream << "\n"; + + currentDate = currentDate.addDays(1); + } + + outputFile.close(); + return true; +} + + /*! * \brief ExportDailyDataCsv * export gridded daily meteo data to csv files * \param variableList list of meteo variables - * \param idListFileName text file of cells id list by columns - if idListFileName is empty save ALL cells + * \param idListFileName text file of cells id list by columns - default (empty): ALL cells * \param outputPath path for output files * \return true on success, false otherwise */ -bool Crit3DMeteoGridDbHandler::exportDailyDataCsv(QString &errorStr, QList variableList, - QDate firstDate, QDate lastDate, QString idListFileName, - QString outputPath, bool isEnsemble) +bool Crit3DMeteoGridDbHandler::exportDailyDataCsv(const QList &variableList, const QDate &firstDate, + const QDate &lastDate, const QString &idListFileName, + QString &outputPath, QString &errorStr) { errorStr = ""; @@ -3989,71 +4047,49 @@ bool Crit3DMeteoGridDbHandler::exportDailyDataCsv(QString &errorStr, QListmeteoPointPointer(row,col)->getMeteoPointValueD(myDate, variableList[i]); - QString valueString = ""; - if (value != NODATA) - valueString = QString::number(value); + isOk = loadGridDailyData(errorStr, id, firstDate, lastDate); + } - out << "," << valueString; - } + if (! isOk) + { + std::cout << "Error in reading cell id: " << id.toStdString() << "\n"; + continue; } - out << "\n"; - currentDate = currentDate.addDays(1); + QString csvFileName = outputPath + "/" + id + ".csv"; + if (! saveDailyDataCsv(csvFileName, variableList, firstDate, lastDate, row, col, errorStr)) + { + std::cout << errorStr.toStdString(); + } } - - outputFile.close(); } } } diff --git a/dbMeteoGrid/dbMeteoGrid.h b/dbMeteoGrid/dbMeteoGrid.h index 11f750e6..be2f384a 100644 --- a/dbMeteoGrid/dbMeteoGrid.h +++ b/dbMeteoGrid/dbMeteoGrid.h @@ -161,8 +161,12 @@ bool activeAllCells(QString *myError); bool setActiveStateCellsInList(QString *myError, QList idList, bool activeState); - bool exportDailyDataCsv(QString &errorStr, QList variableList, - QDate firstDate, QDate lastDate, QString idListFileName, QString outputPath, bool isEnsemble); + bool saveDailyDataCsv(const QString &csvFileName, const QList &variableList, + const QDate &firstDate, const QDate &lastDate, unsigned row, unsigned col, QString &errorStr); + + bool exportDailyDataCsv(const QList &variableList, const QDate &firstDate, + const QDate &lastDate, const QString &idListFileName, QString &outputPath, QString &errorStr); + bool MeteoGridToRasterFlt(double cellSize, const gis::Crit3DGisSettings &gisSettings, gis::Crit3DRasterGrid& myGrid); QDate getFirstDailyDate() const; diff --git a/project/shell.cpp b/project/shell.cpp index 08c93e18..b80e0521 100644 --- a/project/shell.cpp +++ b/project/shell.cpp @@ -288,7 +288,7 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) "ExportDailyDataCsv -v:variableList [-TPREC] [-t:type] -d1:firstDate [-d2:lastDate] [-l:idList] [-p:outputPath]\n" "-v list of comma separated variables (varname: TMIN, TMAX, TAVG, PREC, RHMIN, RHMAX, RHAVG, RAD, ET0_HS, ET0_PM, LEAFW) \n" "-TPREC export Tmin, Tmax, Tavg, Prec \n" - "-t type: GRID|ENSEMBLE_GRID|POINTS (default: GRID) \n" + "-t type: GRID|POINTS (default: GRID) \n" "-d1, -d2 date format: YYYY-MM-DD (default: lastDate = yesterday) \n" "-l list of output points or cells filename (default: ALL active cells/points) \n" "-p output Path (default: " + outputPath + ") \n"; @@ -359,9 +359,9 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) { typeStr = argumentList[i].right(argumentList[i].length()-3).toUpper(); - if (typeStr != "GRID" && typeStr != "POINTS" && typeStr != "ENSEMBLE_GRID") + if (typeStr != "GRID" && typeStr != "POINTS") { - myProject->logError("Wrong type: available GRID or ENSEMBLE_GRID or POINTS."); + myProject->logError("Wrong type: available GRID or POINTS."); return PRAGA_OK; } } @@ -423,7 +423,7 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) myProject->logInfo("... output path is: " + outputPath); - if (typeStr == "GRID" || typeStr == "ENSEMBLE_GRID") + if (typeStr == "GRID") { if (! myProject->meteoGridLoaded) { @@ -431,9 +431,8 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) return PRAGA_ERROR; } - bool isEnsemble = (typeStr == "ENSEMBLE_GRID"); - if (! myProject->meteoGridDbHandler->exportDailyDataCsv(myProject->errorString, variableList, - firstDate, lastDate, idListFileName, outputPath, isEnsemble)) + if (! myProject->meteoGridDbHandler->exportDailyDataCsv(variableList, firstDate, lastDate, + idListFileName, outputPath, myProject->errorString)) { myProject->logError(); return PRAGA_ERROR; From 66ef31436e5c80ea46996f2bebdd669e5d7c1efa Mon Sep 17 00:00:00 2001 From: lauracosta Date: Thu, 6 Jun 2024 15:16:20 +0200 Subject: [PATCH 059/179] fix lastMember --- weatherGenerator/weatherGenerator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/weatherGenerator/weatherGenerator.cpp b/weatherGenerator/weatherGenerator.cpp index 829ba03a..0328dde9 100644 --- a/weatherGenerator/weatherGenerator.cpp +++ b/weatherGenerator/weatherGenerator.cpp @@ -1017,11 +1017,16 @@ bool makeSeasonalForecastWaterTable(QString outputFileName, char separator, XMLS if (indexWg.size() != 0) { QDate myDate(seasonFirstDate.year, seasonFirstDate.month, seasonFirstDate.day); + QDate lastDate(seasonLastDate.year, seasonLastDate.month, seasonLastDate.day); for (int currentIndex = indexWg[0]; currentIndex <= indexWg[indexWg.size()-1]; currentIndex++) { float tmin = dailyPredictions[currentIndex].minTemp; float tmax = dailyPredictions[currentIndex].maxTemp; float prec = dailyPredictions[currentIndex].prec; + if (isLastMember && myDate>lastDate) + { + myDate.setDate(myDate.year()-1, myDate.month(), myDate.day()); // l'ultimo membro puรฒ prendere 2 periodi di wg + } if (waterTable->setMeteoData(myDate, tmin, tmax, prec)) { if (waterTable->getWaterTableInterpolation(myDate, &wtDepth, &myDelta, &myDeltaDays)) From e96cee178b50284b66102800a57600126c1da997 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 15:30:23 +0200 Subject: [PATCH 060/179] fix pivot --- mathFunctions/furtherMathFunctions.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 746969ef..a3a0a95a 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -701,7 +701,7 @@ namespace interpolation double* parametersDelta, double* parametersChange) { int i, j, k; - double pivot, mult, top; + double mult, top; if (nrParameters <= 0) return; @@ -731,7 +731,7 @@ namespace interpolation for (j = 0; j < nrData; j++) { double newEst = estimateFunction(idFunction, parameters, nrParameters, x[j]); - P[i][j] = (newEst - firstEst[j]) / MAXVALUE(parametersDelta[i], EPSILON) ; + P[i][j] = (newEst - firstEst[j]) / std::max(parametersDelta[i], EPSILON); } parameters[i] -= parametersDelta[i]; } @@ -746,7 +746,7 @@ namespace interpolation a[i][j] += P[i][k] * P[j][k]; } } - z[i] = sqrt(a[i][i]) + EPSILON; //? + z[i] = sqrt(a[i][i]) + EPSILON; } for (i = 0; i < nrParameters; i++) @@ -774,7 +774,7 @@ namespace interpolation for (j = 0; j < (nrParameters - 1); j++) { - pivot = a[j][j]; + double pivot = std::max(a[j][j], EPSILON); for (i = j + 1 ; i < nrParameters; i++) { mult = a[i][j] / pivot; @@ -795,7 +795,8 @@ namespace interpolation { top -= a[i][k] * parametersChange[k]; } - parametersChange[i] = top / a[i][i]; + double pivot = std::max(a[i][i], EPSILON); + parametersChange[i] = top / pivot; } for (i = 0; i < nrParameters; i++) From 870113124f06c47cd3201edccb484a1ad63b53af Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 16:08:57 +0200 Subject: [PATCH 061/179] update export daily --- dbMeteoGrid/dbMeteoGrid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbMeteoGrid/dbMeteoGrid.cpp b/dbMeteoGrid/dbMeteoGrid.cpp index b245a669..580322c5 100644 --- a/dbMeteoGrid/dbMeteoGrid.cpp +++ b/dbMeteoGrid/dbMeteoGrid.cpp @@ -1709,7 +1709,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString QString tableD = _tableDaily.prefix + meteoPointId + _tableDaily.postFix; unsigned row, col; - if ( !_meteoGrid->findMeteoPointFromId(&row, &col, meteoPointId.toStdString()) ) + if (! _meteoGrid->findMeteoPointFromId(&row, &col, meteoPointId.toStdString()) ) { myError = "Missing meteoPoint id: " + meteoPointId; return false; @@ -4044,7 +4044,7 @@ bool Crit3DMeteoGridDbHandler::exportDailyDataCsv(const QList &va for (int col = 0; col < gridStructure().header().nrCols; col++) { QString id = QString::fromStdString(meteoGrid()->meteoPoints()[row][col]->id); - if (! isList || idList.contains(id)) + if (idList.contains(id) || (! isList && meteoGrid()->meteoPoints()[row][col]->active)) { // read data if (gridStructure().isEnsemble()) From 24692875838bef2953a2a73d392de807c22b82f8 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 18:24:18 +0200 Subject: [PATCH 062/179] fix pass date to watertable --- waterTable/dialogSummary.cpp | 7 ------- waterTable/waterTable.cpp | 29 +++++++++++++++-------------- waterTable/waterTable.h | 2 -- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/waterTable/dialogSummary.cpp b/waterTable/dialogSummary.cpp index f670d21e..7e73cf13 100644 --- a/waterTable/dialogSummary.cpp +++ b/waterTable/dialogSummary.cpp @@ -38,10 +38,6 @@ DialogSummary::DialogSummary(WaterTable myWaterTable) QLineEdit* myRMSE = new QLineEdit(QString::number(myWaterTable.getRMSE(),'f', 2)); myRMSE->setReadOnly(true); - QLabel* labelNASH = new QLabel("Nash-Sutcliffe [-]: "); - QLineEdit* myNASH = new QLineEdit(QString::number(myWaterTable.getNASH(),'f', 2)); - myNASH->setReadOnly(true); - QLabel* labelEfIndex = new QLabel("Efficiency Index [-]: "); QLineEdit* myEfIndex = new QLineEdit(QString::number(myWaterTable.getEF(),'f', 2)); myEfIndex->setReadOnly(true); @@ -67,9 +63,6 @@ DialogSummary::DialogSummary(WaterTable myWaterTable) infoLayout->addWidget(labelRMSE,6,0,1,1); infoLayout->addWidget(myRMSE,6,1,1,1); - infoLayout->addWidget(labelNASH,7,0,1,1); - infoLayout->addWidget(myNASH,7,1,1,1); - infoLayout->addWidget(labelEfIndex,8,0,1,1); infoLayout->addWidget(myEfIndex,8,1,1,1); diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 3408d4ed..fb2a54f9 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -96,7 +96,6 @@ void WaterTable::initializeWaterTable(Well myWell) nrDaysPeriod = NODATA; nrObsData = 0; EF = NODATA; - NASH = NODATA; RMSE = NODATA; avgDailyCWB = NODATA; } @@ -202,6 +201,7 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) float Tmax = NODATA; float prec = NODATA; float etp = NODATA; + double lat = well.getLatitude(); for (QDate myDate = firstMeteoDate; myDate <= lastMeteoDate; myDate = myDate.addDays(1)) { @@ -219,10 +219,12 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) Tmin = inputTMin[index]; Tmax = inputTMax[index]; prec = inputPrec[index]; - etp = dailyEtpHargreaves(Tmin, Tmax, date, well.getLatitude(), &meteoSettings); + etp = dailyEtpHargreaves(Tmin, Tmax, date, lat, &meteoSettings); } + etpValues.push_back(etp); precValues.push_back(prec); + if (etp != NODATA && prec != NODATA) { sumCWB += prec - etp; @@ -291,22 +293,22 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) } } - if (bestR2 > 0) - { - nrObsData = int(myObsWT.size()); - nrDaysPeriod = bestNrDays; - h0 = bestH0; - alpha = bestAlfaCoeff; - R2 = bestR2; - isCWBEquationReady = true; - return true; - } - else + if (bestR2 < 0.1) { return false; } + + nrObsData = int(myObsWT.size()); + nrDaysPeriod = bestNrDays; + h0 = bestH0; + alpha = bestAlfaCoeff; + R2 = bestR2; + isCWBEquationReady = true; + + return true; } + // Climatic WaterBalance (CWB) on a nrDaysPeriod double WaterTable::computeCWB(QDate myDate, int nrDays) { @@ -400,7 +402,6 @@ bool WaterTable::computeWaterTableIndices() } RMSE = sqrt(mySumError / nrObs); - NASH = 1 - mySumError / mySumDiffAvg; if (isClimateReady) { diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 3e77410c..0c3d9a5b 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -45,7 +45,6 @@ class WaterTable float getR2() const { return R2; } float getRMSE() const { return RMSE; } - float getNASH() const { return NASH; } float getEF() const { return EF; } int getNrDaysPeriod() const { return nrDaysPeriod; } @@ -92,7 +91,6 @@ class WaterTable float R2; float RMSE; - float NASH; float EF; bool isClimateReady; From ee67edc365bbea42540d81811e3b4ebccf96f50d Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 19:41:33 +0200 Subject: [PATCH 063/179] update watertable --- project/project.h | 2 +- waterTable/importData.cpp | 4 +- waterTable/importData.h | 2 +- waterTable/waterTable.cpp | 162 ++++++++++++++++---------------------- waterTable/waterTable.h | 34 ++++---- 5 files changed, 90 insertions(+), 114 deletions(-) diff --git a/project/project.h b/project/project.h index 78fd6f71..a43db47b 100644 --- a/project/project.h +++ b/project/project.h @@ -59,7 +59,7 @@ #define ERROR_STR_MISSING_DEM "Load a Digital Elevation Model (DEM) before." #define ERROR_STR_MISSING_PROJECT "Open a project before." #define ERROR_STR_MISSING_GRID "Load a meteo grid DB before." - #define ERROR_STR_MISSING_POINT_GRID "Load meteo Points or grid." + #define ERROR_STR_MISSING_POINT_GRID "Load meteo points or meteo grid before." class Crit3DMeteoWidget; class FormInfo; diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index e543eb48..4056e0e9 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -215,9 +215,9 @@ bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellL } -bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) +bool loadCsvDepthsSingleWell(const QString &csvFileName, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines) { - QFile myFile(csvDepths); + QFile myFile(csvFileName); QList errorList; int posDate = 0; diff --git a/waterTable/importData.h b/waterTable/importData.h index 4c63bcbf..497e1702 100644 --- a/waterTable/importData.h +++ b/waterTable/importData.h @@ -15,7 +15,7 @@ bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellList, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); - bool loadCsvDepthsSingleWell(QString csvDepths, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); + bool loadCsvDepthsSingleWell(const QString &csvFileName, Well* well, int waterTableMaximumDepth, QString &errorStr, int &wrongLines); #endif // IMPORTDATA_H diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index fb2a54f9..62af08d7 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -10,28 +10,34 @@ WaterTable::WaterTable(std::vector &inputTMin, std::vector &inputT { } -QString WaterTable::getIdWell() const -{ - return well.getId(); -} -QDate WaterTable::getFirstDateWell() +void WaterTable::initializeWaterTable(Well myWell) { - firstDateWell = well.getFirstDate(); - return firstDateWell; -} + well = myWell; -QDate WaterTable::getLastDateWell() -{ - lastDateWell = well.getLastDate(); - return lastDateWell; -} + getFirstDateWell(); + getLastDateWell(); -QMap WaterTable::getObsDepths() -{ - return well.getObsDepths(); + for (int myMonthIndex = 0; myMonthIndex < 12; myMonthIndex++) + { + WTClimateMonthly[myMonthIndex] = NODATA; + } + + isCWBEquationReady = false; + isClimateReady = false; + + alpha = NODATA; + h0 = NODATA; + R2 = NODATA; + nrDaysPeriod = NODATA; + nrObsData = 0; + EF = NODATA; + RMSE = NODATA; + avgDailyCWB = NODATA; + error = ""; } + void WaterTable::setInputTMin(const std::vector &newInputTMin) { inputTMin = newInputTMin; @@ -60,47 +66,6 @@ void WaterTable::cleanAllMeteoVector() } -std::vector WaterTable::getMyDates() -{ - return myDates; -} - -std::vector WaterTable::getMyHindcastSeries() -{ - return myHindcastSeries; -} - -std::vector WaterTable::getMyInterpolateSeries() -{ - return myInterpolateSeries; -} - -void WaterTable::initializeWaterTable(Well myWell) -{ - well = myWell; - - getFirstDateWell(); - getLastDateWell(); - - for (int myMonthIndex = 0; myMonthIndex < 12; myMonthIndex++) - { - WTClimateMonthly[myMonthIndex] = NODATA; - } - - isCWBEquationReady = false; - isClimateReady = false; - - alpha = NODATA; - h0 = NODATA; - R2 = NODATA; - nrDaysPeriod = NODATA; - nrObsData = 0; - EF = NODATA; - RMSE = NODATA; - avgDailyCWB = NODATA; -} - - bool WaterTable::computeWaterTableParameters(Well myWell, int maxNrDays) { if (myWell.getObsDepthNr() == 0) @@ -165,8 +130,10 @@ bool WaterTable::computeWTClimate() } WTClimateMonthly[myMonthIndex] = H_sum[myMonthIndex] / H_num[myMonthIndex]; } - isClimateReady = true; + interpolation::cubicSplineYearInterpolate(WTClimateMonthly, WTClimateDaily); + isClimateReady = true; + return true; } @@ -455,6 +422,7 @@ float WaterTable::getWaterTableClimate(QDate myDate) return getWaterTableClimate; } + bool WaterTable::computeWaterTableClimate(QDate currentDate, int yearFrom, int yearTo, float* myValue) { *myValue = NODATA; @@ -504,6 +472,7 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* { return false; } + // first assessment float myWT_computation = getWaterTableDaily(myDate); if (myWT_computation == NODATA) @@ -525,50 +494,51 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* QDate nextDate; int dT; - // previuos and next observation QMap myDepths = well.getObsDepths(); QList keys = myDepths.keys(); + + // check previuos and next observed data + int lastIndex = keys.size() - 1; int i = keys.indexOf(myDate); if (i != -1) // exact data found { - if (i > 0) - { - indexPrev = i - 1; - indexNext = i; - } - if (i < keys.size()-1) - { - indexPrev = i; - indexNext = i + 1; - } + indexPrev = i; previousDate = keys[indexPrev]; previosValue = myDepths[previousDate]; + indexNext = i; nextDate = keys[indexNext]; nextValue = myDepths[nextDate]; } else { - for (int i = 0; i myDate) { - if (i == 0 && keys[i] > myDate) - { - indexNext = i; - nextDate = keys[indexNext]; - nextValue = myDepths[nextDate]; - break; - } - else if (keys[i] < myDate && keys[i+1] > myDate) - { - indexPrev = i; - previousDate = keys[indexPrev]; - previosValue = myDepths[previousDate]; - indexNext = i + 1; - nextDate = keys[indexNext]; - nextValue = myDepths[nextDate]; - break; - } + indexNext = i; + nextDate = keys[indexNext]; + nextValue = myDepths[nextDate]; + } + else if (keys[lastIndex] < myDate) + { + indexPrev = i; + previousDate = keys[indexPrev]; + previosValue = myDepths[previousDate]; + } + else + { + for (int i = 0; i < lastIndex; i++) + if (keys[i] < myDate && keys[i+1] > myDate) + { + indexPrev = i; + previousDate = keys[indexPrev]; + previosValue = myDepths[previousDate]; + indexNext = i + 1; + nextDate = keys[indexNext]; + nextValue = myDepths[nextDate]; + break; + } } } + if (indexPrev != NODATA) { myWT = getWaterTableDaily(previousDate); @@ -594,7 +564,7 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* dT = previousDate.daysTo(nextDate); if (dT > WATERTABLE_MAXDELTADAYS * 2) { - if ( diffWithPrev <= diffWithNext) + if (diffWithPrev <= diffWithNext) { nextDz = NODATA; } @@ -608,16 +578,24 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* if (previousDz != NODATA && nextDz != NODATA) { dT = previousDate.daysTo(nextDate); - *myDelta = previousDz * (1.0 - (float(diffWithPrev) / float(dT))) + nextDz * (1.0 - (float(diffWithNext) / float(dT))); - *myDeltaDays = std::min(diffWithPrev, diffWithNext); + if (dT == 0) + { + *myDelta = previousDz; + *myDeltaDays = 0; + } + else + { + *myDelta = previousDz * (1.0 - (float(diffWithPrev) / float(dT))) + nextDz * (1.0 - (float(diffWithNext) / float(dT))); + *myDeltaDays = std::min(diffWithPrev, diffWithNext); + } } - else if ( previousDz!= NODATA) + else if (previousDz != NODATA) { dT = diffWithPrev; *myDelta = previousDz * std::max((1.f - (float(dT) / float(WATERTABLE_MAXDELTADAYS))), 0.f); *myDeltaDays = dT; } - else if ( nextDz!= NODATA) + else if (nextDz != NODATA) { dT = diffWithNext; *myDelta = nextDz * std::max((1.f - (float(dT) / float(WATERTABLE_MAXDELTADAYS))), 0.f); diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index 0c3d9a5b..df9e8d01 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -21,9 +21,6 @@ class WaterTable WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, Crit3DMeteoSettings meteoSettings); - QString getIdWell() const; - QDate getFirstDateWell(); - QDate getLastDateWell(); void initializeWaterTable(Well myWell); bool computeWaterTableParameters(Well myWell, int maxNrDays); bool computeWTClimate(); @@ -36,8 +33,16 @@ class WaterTable bool computeWaterTableClimate(QDate currentDate, int yearFrom, int yearTo, float* myValue); bool getWaterTableInterpolation(QDate myDate, float* myValue, float* myDelta, int* myDeltaDays); void computeWaterTableSeries(); + bool setMeteoData(QDate myDate, float tmin, float tmax, float prec); + void setInputTMin(const std::vector &newInputTMin); + void setInputTMax(const std::vector &newInputTMax); + void setInputPrec(const std::vector &newInputPrec); + + void setFirstMeteoDate(QDate myDate) { firstMeteoDate = myDate; } + void setLastMeteoDate(QDate myDate) { lastMeteoDate = myDate; } + QString getError() const { return error; } double getAlpha() const { return alpha; } @@ -50,30 +55,23 @@ class WaterTable int getNrDaysPeriod() const { return nrDaysPeriod; } int getNrObsData() const { return nrObsData; } - std::vector getMyDates(); - std::vector getMyHindcastSeries(); - std::vector getMyInterpolateSeries(); - QMap getObsDepths(); + QString getIdWell() const { return well.getId(); } + QDate getFirstDateWell() { return well.getFirstDate(); } + QDate getLastDateWell() { return well.getLastDate(); } - void cleanAllMeteoVector(); - - void setInputTMin(const std::vector &newInputTMin); + QMap getObsDepths() { return well.getObsDepths(); } - void setInputTMax(const std::vector &newInputTMax); + std::vector getMyDates() { return myDates; } - void setInputPrec(const std::vector &newInputPrec); + std::vector getMyHindcastSeries() { return myHindcastSeries; } - void setFirstMeteoDate(QDate myDate) - { firstMeteoDate = myDate; } + std::vector getMyInterpolateSeries() { return myInterpolateSeries; } - void setLastMeteoDate(QDate myDate) - { lastMeteoDate = myDate; } + void cleanAllMeteoVector(); private: Crit3DMeteoSettings meteoSettings; - QDate firstDateWell; - QDate lastDateWell; QDate firstMeteoDate; QDate lastMeteoDate; Well well; From aa589e313106fb30ac980df24fec06b315d9459e Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 19:55:40 +0200 Subject: [PATCH 064/179] fix index interpolation watertable --- waterTable/waterTable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 62af08d7..a94b2902 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -513,13 +513,13 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* { if (keys[0] > myDate) { - indexNext = i; + indexNext = 0; nextDate = keys[indexNext]; nextValue = myDepths[nextDate]; } else if (keys[lastIndex] < myDate) { - indexPrev = i; + indexPrev = lastIndex; previousDate = keys[indexPrev]; previosValue = myDepths[previousDate]; } From b3dfcd0dcb440ed9736dda548b27e8a14a2b1043 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 6 Jun 2024 20:06:00 +0200 Subject: [PATCH 065/179] update error --- project/project.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 7d97368f..b0c494c3 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4683,14 +4683,14 @@ bool Project::computeSingleWell(int indexWell) return false; } - if (!assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) + if (! assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) { - logError("Missing near weather data"); + logError("Missing weather data near well: " + wellPoints[indexWell].getId()); return false; } if (linkedMeteoPoint.nrObsDataDaysD == 0) { - logError("Missing near weather data"); + logError("Missing weather data near well: " + wellPoints[indexWell].getId()); return false; } From efb242980e1fdb86961b7b361795392b98789b3c Mon Sep 17 00:00:00 2001 From: cate-to Date: Fri, 7 Jun 2024 12:44:29 +0200 Subject: [PATCH 066/179] fix multiple detrending --- interpolation/interpolation.cpp | 57 ++++++++------------------ mathFunctions/furtherMathFunctions.cpp | 2 +- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 8be6e470..0d1648f9 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1020,11 +1020,7 @@ void localSelection(vector &inputPoints, vector < float x, float y, Crit3DInterpolationSettings& mySettings) { // search more stations to assure min points with all valid proxies - float ratioMinPoints; - if (mySettings.getUseLapseRateCode()) - ratioMinPoints = float(2); - else - ratioMinPoints = float(1.3); + float ratioMinPoints = float(1.3); unsigned minPoints = unsigned(mySettings.getMinPointsLocalDetrending() * ratioMinPoints); if (inputPoints.size() <= minPoints) { @@ -1041,9 +1037,10 @@ void localSelection(vector &inputPoints, vector < float r0 = 0; // [m] float r1 = stepRadius; // [m] unsigned int i; + unsigned int nrPrimaries = 0; float maxDistance = 0; - while (nrValid < minPoints) + while (nrValid < minPoints || (mySettings.getUseLapseRateCode() && nrPrimaries < minPoints)) { maxDistance = 0; for (i=0; i < inputPoints.size(); i++) @@ -1054,27 +1051,17 @@ void localSelection(vector &inputPoints, vector < nrValid++; if (inputPoints[i].distance > maxDistance) maxDistance = inputPoints[i].distance; + + if (checkLapseRateCode(inputPoints[i].lapseRateCode, mySettings.getUseLapseRateCode(), true)) + nrPrimaries++; } } r0 = r1; r1 += stepRadius; } - /* //same number of stations for all cells - unsigned newIndex = selectedPoints.size(); - std::vector outputPoints; - if (nrValid > minPoints+1) - { - newIndex = sortPointsByDistance(minPoints + 1, selectedPoints, outputPoints); - while (outputPoints.size() > minPoints+1) - outputPoints.pop_back(); - } - selectedPoints.clear(); - selectedPoints = outputPoints; -*/ - for (i=0; i< selectedPoints.size(); i++) - selectedPoints[i].regressionWeight = (1 - selectedPoints[i].distance / maxDistance); + selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / maxDistance,2*EPSILON); mySettings.setLocalRadius(maxDistance); } @@ -1743,10 +1730,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st isValid = true; proxyValue = it->getProxyValue(elevationPos); if (proxyValue == NODATA) - { isValid = false; - break; - } if (! isValid) it = myPoints.erase(it); @@ -1760,10 +1744,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st isValid = true; proxyValue = it->getProxyValue(elevationPos); if (proxyValue == NODATA) - { isValid = false; - break; - } if (! isValid) it = elevationPoints.erase(it); @@ -1822,7 +1803,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st //std::vector > parameters; std::vector&)>> myFunc; - unsigned int nrMaxStep = 20; + unsigned int nrMaxStep = 80; if (parameters.empty()) nrMaxStep *= 10; @@ -1853,8 +1834,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st float detrendValue; for (i = 0; i < myPoints.size(); i++) { - if (checkLapseRateCode(myPoints[i].lapseRateCode, mySettings->getUseLapseRateCode(), true)) - proxyValue = myPoints[i].getProxyValue(elevationPos); + proxyValue = myPoints[i].getProxyValue(elevationPos); detrendValue = float((*func)(proxyValue, parameters[elevationPos])); myPoints[i].value -= detrendValue; @@ -2075,20 +2055,19 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetUseLapseRateCode(), false)) + + for (int pos=0; pos < proxyNr; pos++) { - for (int pos=0; pos < proxyNr; pos++) + if ((othersCombination.isProxyActive(pos)) && othersCombination.isProxySignificant(pos)) { - if ((othersCombination.isProxyActive(pos)) && othersCombination.isProxySignificant(pos)) - { - proxyValue = myPoints[i].getProxyValue(pos); - proxyValues.push_back(double(proxyValue)); - } + proxyValue = myPoints[i].getProxyValue(pos); + proxyValues.push_back(double(proxyValue)); } - - detrendValue = float(functionSum(myFunc, proxyValues, parameters)); - myPoints[i].value -= detrendValue; } + + detrendValue = float(functionSum(myFunc, proxyValues, parameters)); + myPoints[i].value -= detrendValue; + } return true; diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index a3a0a95a..275904e8 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -2123,7 +2123,7 @@ namespace interpolation for (j = 0; j < (nrParameters - 1); j++) { - pivot = a[j][j]; + pivot = std::max(a[j][j],EPSILON); for (i = j + 1 ; i < nrParameters; i++) { mult = a[i][j] / pivot; From a12fd5bc3362bad4f7047e7b3ca778c525cc9bea Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 7 Jun 2024 13:18:22 +0200 Subject: [PATCH 067/179] update --- project/project.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index b0c494c3..083496d4 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4683,14 +4683,15 @@ bool Project::computeSingleWell(int indexWell) return false; } + QString idStr = wellPoints[indexWell].getId(); if (! assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) { - logError("Missing weather data near well: " + wellPoints[indexWell].getId()); + logError("Missing weather data near well: " + idStr); return false; } if (linkedMeteoPoint.nrObsDataDaysD == 0) { - logError("Missing weather data near well: " + wellPoints[indexWell].getId()); + logError("Missing weather data near well: " + idStr); return false; } From edfb163c0d8d12852a603664845e875caddc2301 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 7 Jun 2024 13:22:20 +0200 Subject: [PATCH 068/179] fig git problem --- project/project.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 7d97368f..083496d4 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4683,14 +4683,15 @@ bool Project::computeSingleWell(int indexWell) return false; } - if (!assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) + QString idStr = wellPoints[indexWell].getId(); + if (! assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) { - logError("Missing near weather data"); + logError("Missing weather data near well: " + idStr); return false; } if (linkedMeteoPoint.nrObsDataDaysD == 0) { - logError("Missing near weather data"); + logError("Missing weather data near well: " + idStr); return false; } From 0faf4153dd824bffdf06b1fb170351c65d0c533a Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 7 Jun 2024 16:18:08 +0200 Subject: [PATCH 069/179] update --- gis/gis.cpp | 6 ++++- gis/gis.h | 2 ++ waterTable/importData.cpp | 49 +++++++++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index 6acbad89..ef6f831f 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -807,7 +807,6 @@ namespace gis gis::utmToLatLon(gisSettings.utmZone, gisSettings.startLocation.latitude, utmX, utmY, myLat, myLon); } - void getLatLonFromUtm(const Crit3DGisSettings& gisSettings, const Crit3DUtmPoint& utmPoint, Crit3DGeoPoint& geoPoint) { gis::utmToLatLon(gisSettings.utmZone, gisSettings.startLocation.latitude, utmPoint.x, utmPoint.y, &(geoPoint.latitude), &(geoPoint.longitude)); @@ -894,6 +893,11 @@ namespace gis latLonToUtmForceZone(zoneNumber, geoPoint.latitude, geoPoint.longitude, &(utmPoint->x), &(utmPoint->y)); } + void getUtmFromLatLon(const Crit3DGisSettings& gisSettings, double latitude, double longitude, double *utmX, double *utmY) + { + latLonToUtmForceZone(gisSettings.utmZone, latitude, longitude, utmX, utmY); + } + /*! \brief equivalent to latLonToUtm forcing UTM zone. diff --git a/gis/gis.h b/gis/gis.h index e604e2a5..9692ee6b 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -242,7 +242,9 @@ bool getNorthernEmisphere(); void getLatLonFromUtm(const Crit3DGisSettings& gisSettings, double utmX,double utmY, double *myLat, double *myLon); void getLatLonFromUtm(const Crit3DGisSettings& gisSettings, const Crit3DUtmPoint& utmPoint, Crit3DGeoPoint& geoPoint); + void getUtmFromLatLon(int zoneNumber, const Crit3DGeoPoint& geoPoint, Crit3DUtmPoint* utmPoint); + void getUtmFromLatLon(const Crit3DGisSettings& gisSettings, double latitude, double longitude, double *utmX, double *utmY); void latLonToUtm(double lat, double lon,double *utmEasting,double *utmNorthing,int *zoneNumber); void latLonToUtmForceZone(int zoneNumber, double lat, double lon, double *utmEasting, double *utmNorthing); diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index 4056e0e9..633abc47 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -23,20 +23,22 @@ bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &we int nrRequiredFields = 3; // check header + bool isLatLon = false; QString line = in.readLine(); QList headerItems = line.split(","); if (headerItems.size() != nrRequiredFields) { - errorStr = "Wrong data! Required well ID, utm X, utm Y."; + errorStr = "Wrong data! Required ID, utmX, utmY or ID, lat, lon."; return false; } - errorStr = ""; + if (headerItems[1].toUpper() == "LAT") + { + isLatLon = true; + } + errorStr = ""; QList idList; QList errorList; - int posId = 0; - int posUtmx = 1; - int posUtmy = 2; int validLines = 0; while (! in.atEnd()) @@ -46,43 +48,54 @@ bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &we items.removeAll({}); if (items.size() < nrRequiredFields) { - errorList.append(items[posId]); + errorList.append(line); wrongLines++; continue; } - items[posId] = items[posId].simplified(); - QString id = items[posId].remove(QChar('"')); + items[0] = items[0].simplified(); + QString id = items[0].remove(QChar('"')); if (idList.contains(id)) { // id already saved - errorList.append(id); + errorList.append(line + "(REPEATED)"); wrongLines++; continue; } idList.append(id); bool isOk; - items[posUtmx] = items[posUtmx].simplified(); - double utmX = items[posUtmx].remove(QChar('"')).toDouble(&isOk); + items[1] = items[1].simplified(); + double value1 = items[1].remove(QChar('"')).toDouble(&isOk); if (! isOk) { - errorList.append(id); + errorList.append(line); wrongLines++; continue; } - items[posUtmy] = items[posUtmy].simplified(); - double utmY = items[posUtmy].remove(QChar('"')).toDouble(&isOk); + items[2] = items[2].simplified(); + double value2 = items[2].remove(QChar('"')).toDouble(&isOk); if (! isOk) { - errorList.append(id); + errorList.append(line); wrongLines++; continue; } - double lat, lon; - gis::getLatLonFromUtm(gisSettings, utmX, utmY, &lat, &lon); + double utmX, utmY, lat, lon; + if (isLatLon) + { + lat = value1; + lon = value2; + gis::getUtmFromLatLon(gisSettings, lat, lon, &utmX, &utmY); + } + else + { + utmX = value1; + utmY = value2; + gis::getLatLonFromUtm(gisSettings, utmX, utmY, &lat, &lon); + } Well newWell; newWell.setId(id); @@ -105,7 +118,7 @@ bool loadWaterTableLocationCsv(const QString &csvFileName, std::vector &we if (wrongLines > 0) { - errorStr = "ID repeated or with invalid coordinates: " + errorList.join(","); + errorStr = "ID repeated or with invalid coordinates:\n" + errorList.join("\n"); } return true; From 83f8c19881189f7cede7d095f689bb1bcfecf4a7 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 7 Jun 2024 17:20:30 +0200 Subject: [PATCH 070/179] fix marquardt --- interpolation/interpolation.cpp | 2 +- mathFunctions/furtherMathFunctions.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 0d1648f9..5364e0ca 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1488,7 +1488,7 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 proxyParamMin.push_back(min_); proxyParamMax.push_back(max_); proxyParamDelta.push_back((max_ - min_) / RATIO_DELTA); - proxyParamFirstGuess.push_back((max_ - min_) / 2); + proxyParamFirstGuess.push_back((max_ + min_) / 2); // TODO check if ok } paramMin.push_back(proxyParamMin); diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 275904e8..4eedef95 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -2135,8 +2135,7 @@ namespace interpolation } } - - paramChange[nrParameters -1] = g[nrParameters - 1] / a[nrParameters - 1][nrParameters - 1]; + paramChange[nrParameters -1] = g[nrParameters - 1] / std::max(a[nrParameters - 1][nrParameters - 1], EPSILON); for (i = nrParameters - 2; i >= 0; i--) { @@ -2145,7 +2144,7 @@ namespace interpolation { top -= a[i][k] * paramChange[k]; } - paramChange[i] = top / a[i][i]; + paramChange[i] = top / std::max(a[i][i], EPSILON); } // change parameters From e554128473acfb0c8c2534300b871925ba521e3a Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 7 Jun 2024 19:31:05 +0200 Subject: [PATCH 071/179] update waterTable --- project/project.cpp | 47 +++++++++-------- project/project.h | 8 +-- waterTable/waterTable.cpp | 103 ++++++++++++++++++-------------------- waterTable/waterTable.h | 8 +-- 4 files changed, 82 insertions(+), 84 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 083496d4..60127499 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -17,6 +17,7 @@ #include "importData.h" #include "dialogSummary.h" #include "waterTableWidget.h" +#include "utilities.h" #include @@ -4629,7 +4630,7 @@ bool Project::waterTableImportLocation(const QString &csvFileName) { logInfo(errorString); QMessageBox::warning(nullptr, "Warning!", QString::number(wrongLines) - + " wrong lines of data were not loaded, see the log file for more information: " + logFileName); + + " wrong lines of data were not loaded\nSee the log file for more information:\n" + logFileName); } errorString = ""; @@ -4650,7 +4651,7 @@ bool Project::waterTableImportDepths(const QString &csvDepthsFileName) { logInfo(errorString); QMessageBox::warning(nullptr, "Warning!", QString::number(wrongLines) - + " wrong lines of data were not loaded, see the log file for more information: " + logFileName); + + " wrong lines of data were not loaded\nSee the log file for more information:\n" + logFileName); } errorString = ""; @@ -4658,7 +4659,7 @@ bool Project::waterTableImportDepths(const QString &csvDepthsFileName) } -bool Project::computeSingleWell(int indexWell) +bool Project::waterTableComputeSingleWell(int indexWell) { if (indexWell == NODATA) return false; @@ -4684,7 +4685,7 @@ bool Project::computeSingleWell(int indexWell) } QString idStr = wellPoints[indexWell].getId(); - if (! assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) + if (! waterTableAssignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) { logError("Missing weather data near well: " + idStr); return false; @@ -4695,8 +4696,6 @@ bool Project::computeSingleWell(int indexWell) return false; } - int maxNrDays = 730; // attualmente fisso - std::vector inputTMin; std::vector inputTMax; std::vector inputPrec; @@ -4712,11 +4711,11 @@ bool Project::computeSingleWell(int indexWell) inputPrec.push_back(prec); } - QDate firstDate(linkedMeteoPoint.getFirstDailyData().year, linkedMeteoPoint.getFirstDailyData().month, linkedMeteoPoint.getFirstDailyData().day); - QDate lastDate(linkedMeteoPoint.getLastDailyData().year, linkedMeteoPoint.getLastDailyData().month, linkedMeteoPoint.getLastDailyData().day); + WaterTable waterTable(inputTMin, inputTMax, inputPrec, getQDate(linkedMeteoPoint.getFirstDailyData()), + getQDate(linkedMeteoPoint.getLastDailyData()), *meteoSettings); + + waterTable.computeWaterTableParameters(wellPoints[indexWell], 5); - WaterTable waterTable(inputTMin, inputTMax, inputPrec, firstDate, lastDate, *meteoSettings); - waterTable.computeWaterTableParameters(wellPoints[indexWell], maxNrDays); waterTable.computeWaterTableSeries(); // prepare series to show waterTableList.push_back(waterTable); @@ -4724,7 +4723,7 @@ bool Project::computeSingleWell(int indexWell) } -void Project::showSingleWell(WaterTable &waterTable, const QString &idWell) +void Project::waterTableShowSingleWell(WaterTable &waterTable, const QString &idWell) { DialogSummary* dialogResult = new DialogSummary(waterTable); // show results dialogResult->show(); @@ -4735,10 +4734,11 @@ void Project::showSingleWell(WaterTable &waterTable, const QString &idWell) return; } -bool Project::assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint) + +bool Project::waterTableAssignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint) { float minimumDistance = NODATA; - bool assignNearestMeteoPoint = false; + bool isFound = false; if (isMeteoGridLoaded) { std::string assignNearestId; @@ -4746,6 +4746,7 @@ bool Project::assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, d unsigned int assignNearestCol; int zoneNumber; QDate lastDate = this->meteoGridDbHandler->getLastDailyDate(); + QDate firstDate = std::max(firstMeteoDate, this->meteoGridDbHandler->getFirstDailyDate()); for (unsigned row = 0; row < unsigned(meteoGridDbHandler->meteoGrid()->gridStructure().header().nrRows); row++) { for (unsigned col = 0; col < unsigned(meteoGridDbHandler->meteoGrid()->gridStructure().header().nrCols); col++) @@ -4769,16 +4770,16 @@ bool Project::assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, d assignNearestId = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->id; assignNearestRow = row; assignNearestCol = col; - assignNearestMeteoPoint = true; + isFound = true; } } } } } - if (assignNearestMeteoPoint) + if (isFound) { - meteoGridDbHandler->loadGridDailyMeteoPrec(errorString, QString::fromStdString(assignNearestId), firstMeteoDate, lastDate); - if (!assignWTMeteoData(meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol), firstMeteoDate)) + meteoGridDbHandler->loadGridDailyMeteoPrec(errorString, QString::fromStdString(assignNearestId), firstDate, lastDate); + if (! waterTableAssignMeteoData(meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow, assignNearestCol), firstDate)) { return false; } @@ -4807,16 +4808,16 @@ bool Project::assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, d if (myDistance < minimumDistance || minimumDistance == NODATA) { meteoPointsDbHandler->loadDailyData(getCrit3DDate(firstMeteoDate), getCrit3DDate(lastDate), &(meteoPoints[i])); - if (assignWTMeteoData(&meteoPoints[i], firstMeteoDate)) + if (waterTableAssignMeteoData(&meteoPoints[i], firstMeteoDate)) { minimumDistance = myDistance; - assignNearestMeteoPoint = true; + isFound = true; assignNearestIndex = i; } } } } - if (assignNearestMeteoPoint) + if (isFound) { linkedMeteoPoint->id = meteoPoints[assignNearestIndex].id; linkedMeteoPoint->name = meteoPoints[assignNearestIndex].name; @@ -4825,10 +4826,12 @@ bool Project::assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, d linkedMeteoPoint->obsDataD = meteoPoints[assignNearestIndex].obsDataD; } } - return assignNearestMeteoPoint; + + return isFound; } -bool Project::assignWTMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate) + +bool Project::waterTableAssignMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate) { QDate lastMeteoDate; lastMeteoDate.setDate(linkedMeteoPoint->getLastDailyData().year, linkedMeteoPoint->getLastDailyData().month, linkedMeteoPoint->getLastDailyData().day); // ultimo dato disponibile diff --git a/project/project.h b/project/project.h index a43db47b..a2757c0c 100644 --- a/project/project.h +++ b/project/project.h @@ -302,10 +302,10 @@ bool waterTableImportLocation(const QString &csvFileName); bool waterTableImportDepths(const QString &csvDepthsFileName); - bool computeSingleWell(int indexWell); - void showSingleWell(WaterTable &waterTable, const QString &idWell); - bool assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint); - bool assignWTMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate); + bool waterTableComputeSingleWell(int indexWell); + void waterTableShowSingleWell(WaterTable &waterTable, const QString &idWell); + bool waterTableAssignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint); + bool waterTableAssignMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate); private slots: void deleteMeteoWidgetPoint(int id); diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index a94b2902..01660c96 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -34,7 +34,7 @@ void WaterTable::initializeWaterTable(Well myWell) EF = NODATA; RMSE = NODATA; avgDailyCWB = NODATA; - error = ""; + errorStr = ""; } @@ -66,11 +66,11 @@ void WaterTable::cleanAllMeteoVector() } -bool WaterTable::computeWaterTableParameters(Well myWell, int maxNrDays) +bool WaterTable::computeWaterTableParameters(Well myWell, int stepDays) { if (myWell.getObsDepthNr() == 0) { - error = "No WaterTable data loaded."; + errorStr = "No WaterTable data loaded."; return false; } @@ -82,7 +82,7 @@ bool WaterTable::computeWaterTableParameters(Well myWell, int maxNrDays) return false; } - isCWBEquationReady = computeCWBCorrelation(maxNrDays); + isCWBEquationReady = computeCWBCorrelation(stepDays); if (! isCWBEquationReady) { return false; @@ -96,7 +96,7 @@ bool WaterTable::computeWTClimate() { if (well.getObsDepthNr() < 3) { - error = "Missing data"; + errorStr = "Missing data"; return false; } @@ -125,7 +125,7 @@ bool WaterTable::computeWTClimate() { if (H_num[myMonthIndex] < 2) { - error = "Missing watertable data: month " + QString::number(myMonthIndex+1); + errorStr = "Missing watertable data: month " + QString::number(myMonthIndex+1); return false; } WTClimateMonthly[myMonthIndex] = H_sum[myMonthIndex] / H_num[myMonthIndex]; @@ -161,33 +161,30 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) etpValues.clear(); precValues.clear(); - float sumCWB = 0; - int nrValidDays = 0; - int index = 0; + if (inputTMin.size() != inputTMax.size() || inputTMin.size() != inputPrec.size()) + { + errorStr = "Wrong weather size"; + return false; + } + float Tmin = NODATA; float Tmax = NODATA; float prec = NODATA; float etp = NODATA; double lat = well.getLatitude(); - for (QDate myDate = firstMeteoDate; myDate <= lastMeteoDate; myDate = myDate.addDays(1)) + float sumCWB = 0; + int nrValidDays = 0; + int nrOfData = (int)inputTMin.size(); + for (int i = 0; i < nrOfData; i++) { - Crit3DDate date(myDate.day(), myDate.month(), myDate.year()); - if (index > inputTMin.size() || index > inputTMax.size() || index > inputPrec.size()) - { - etp = NODATA; - if (index < inputPrec.size()) - { - prec = inputPrec[index]; - } - } - else - { - Tmin = inputTMin[index]; - Tmax = inputTMax[index]; - prec = inputPrec[index]; - etp = dailyEtpHargreaves(Tmin, Tmax, date, lat, &meteoSettings); - } + QDate currentDate = firstMeteoDate.addDays(i); + Crit3DDate myDate = Crit3DDate(currentDate.day(), currentDate.month(), currentDate.year()); + + Tmin = inputTMin[i]; + Tmax = inputTMax[i]; + prec = inputPrec[i]; + etp = dailyEtpHargreaves(Tmin, Tmax, myDate, lat, &meteoSettings); etpValues.push_back(etp); precValues.push_back(prec); @@ -195,9 +192,8 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) if (etp != NODATA && prec != NODATA) { sumCWB += prec - etp; - nrValidDays = nrValidDays + 1; + nrValidDays++; } - index = index + 1; } if (isUpdateAvgCWB) @@ -208,7 +204,7 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) } else { - error = "Missing data"; + errorStr = "Missing data"; return false; } } @@ -218,20 +214,21 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) // Ricerca del periodo di correlazione migliore -bool WaterTable::computeCWBCorrelation(int maxNrDays) +bool WaterTable::computeCWBCorrelation(int stepDays) { - float bestR2 = 0; - float bestH0; - float bestAlfaCoeff; - int bestNrDays = NODATA; QMap myDepths = well.getObsDepths(); std::vector myCWBSum; std::vector myObsWT; - float a, b; - float currentR2; + float a = NODATA; + float b = NODATA; + float currentR2 = NODATA; + float bestR2 = 0; + float bestH0 = NODATA; + float bestAlfaCoeff = NODATA; + int bestNrDays = NODATA; - maxNrDays = std::max(90, maxNrDays); - for (int nrDays = 90; nrDays <= maxNrDays; nrDays += 5) + int maxNrDays = 730; // two years + for (int nrDays = 90; nrDays <= maxNrDays; nrDays += stepDays) { myCWBSum.clear(); myObsWT.clear(); @@ -302,7 +299,7 @@ double WaterTable::computeCWB(QDate myDate, int nrDays) if (nrValidDays < (nrDays * meteoSettings.getMinimumPercentage() / 100)) { - error = "Few Data"; + errorStr = "Few Data"; return NODATA; } @@ -341,7 +338,7 @@ bool WaterTable::computeWaterTableIndices() statistics::linearRegression(myObs, myComputed, int(myObs.size()), false, &myIntercept, &myCoeff, &R2); float mySum = 0; - float mySumError = 0; + float mySumerrorStr = 0; float mySumDiffClimate = 0; float mySumDiffAvg = 0; float myErr = 0; @@ -358,7 +355,7 @@ bool WaterTable::computeWaterTableIndices() for (int i=0; i myDepths = well.getObsDepths(); - QMapIterator it(myDepths); - myDates.clear(); myHindcastSeries.clear(); myInterpolateSeries.clear(); float myDelta; int myDeltaDays; - QDate firstObsDate = well.getFirstDate(); + QDate firstObsDate = std::min(well.getFirstDate(), firstMeteoDate); int numValues = firstObsDate.daysTo(lastMeteoDate) + 1; + for (int i = 0; i < numValues; i++) { - QDate myDate = firstObsDate.addDays(i); - myDates.push_back(myDate); + QDate currentDate = firstObsDate.addDays(i); + myDates.push_back(currentDate); - float myDepth = getWaterTableDaily(myDate); - myHindcastSeries.push_back(myDepth); + float currentDepth = getWaterTableDaily(currentDate); + myHindcastSeries.push_back(currentDepth); - if (getWaterTableInterpolation(myDate, &myDepth, &myDelta, &myDeltaDays)) + if (getWaterTableInterpolation(currentDate, ¤tDepth, &myDelta, &myDeltaDays)) { - myInterpolateSeries.push_back(myDepth); + myInterpolateSeries.push_back(currentDepth); } else { diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index df9e8d01..b31075ee 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -22,10 +22,10 @@ class WaterTable QDate firstMeteoDate, QDate lastMeteoDate, Crit3DMeteoSettings meteoSettings); void initializeWaterTable(Well myWell); - bool computeWaterTableParameters(Well myWell, int maxNrDays); + bool computeWaterTableParameters(Well myWell, int stepDays); bool computeWTClimate(); bool computeETP_allSeries(bool isUpdateAvgCWB); - bool computeCWBCorrelation(int maxNrDays); + bool computeCWBCorrelation(int stepDays); double computeCWB(QDate myDate, int nrDays); bool computeWaterTableIndices(); float getWaterTableDaily(QDate myDate); @@ -43,7 +43,7 @@ class WaterTable void setFirstMeteoDate(QDate myDate) { firstMeteoDate = myDate; } void setLastMeteoDate(QDate myDate) { lastMeteoDate = myDate; } - QString getError() const { return error; } + QString getError() const { return errorStr; } double getAlpha() const { return alpha; } double getH0() const { return h0; } @@ -75,7 +75,7 @@ class WaterTable QDate firstMeteoDate; QDate lastMeteoDate; Well well; - QString error; + QString errorStr; std::vector inputTMin; std::vector inputTMax; From e91397c4d3b88a02376414a26db4682c1b708c6b Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Mon, 10 Jun 2024 17:15:54 +0200 Subject: [PATCH 072/179] fixed bug --- interpolation/interpolation.cpp | 2 +- mathFunctions/furtherMathFunctions.cpp | 29 +++++++++++++++++++++++--- project/project.cpp | 5 +++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 5364e0ca..046a38a1 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1803,7 +1803,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st //std::vector > parameters; std::vector&)>> myFunc; - unsigned int nrMaxStep = 80; + unsigned int nrMaxStep = 20; if (parameters.empty()) nrMaxStep *= 10; diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 4eedef95..8127390c 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -1975,14 +1975,28 @@ namespace interpolation std::random_device rd; std::mt19937 gen(rd()); std::normal_distribution normal_dis(0.5, 0.5); + //std::normal_distribution normal_dis(25, 20); double truncNormal; + std::vector > discreteParameters; + int nrDiscrete = 50; + std::uniform_int_distribution<> distribuzione(0, 49); + std::vector tempDiscrete; + for (int j = 0; j < parameters.size()-2; j++) + { + for (int i = 0; i < nrDiscrete; i++) + tempDiscrete.push_back(parametersMin[j]+i*((parametersMax[j]-parametersMin[j])/nrDiscrete)); + + discreteParameters.push_back(tempDiscrete); + tempDiscrete.clear(); + } + do { fittingMarquardt_nDimension_noSquares_singleFunction(func,parametersMin, parametersMax,parameters, parametersDelta,maxIterationsNr, - myEpsilon,x,y,weights); + myEpsilon,x,y,weights); for (i=0;i= 1.0); parameters[j] = parametersMin[j] + (truncNormal)*(parametersMax[j]-parametersMin[j]); + }*/ + + int indice = 0; + for (j=0; j= discreteParameters[j].size()); + parameters[j] = discreteParameters[j][indice]; } - } while( (counter < nrTrials) && !(R2Previous[0] > 0.8 && R2Previous[nrMinima-1] > 0.8) && (fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2) ); + } while( (counter < nrTrials) && !(R2Previous[0] > 0.797 && R2Previous[nrMinima-1] > 0.8) && ((R2Previous[0] == NODATA) || fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2 )); for (j=0; jvalue[row][col] = interpolate(subsetInterpolationPoints, &interpolationSettings, meteoSettings, myVar, x, y, z, proxyValues, true); - if (interpolationSettings.getUseLocalDetrending()) - myRaster->setParametersForRowCol(row, col, interpolationSettings.getFittingParameters()); + + myRaster->setParametersForRowCol(row, col, interpolationSettings.getFittingParameters()); + interpolationSettings.setCurrentCombination(interpolationSettings.getSelectedCombination()); } } } From 5214e6d907af2db831031b31538958719216ca8d Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 11 Jun 2024 16:30:26 +0200 Subject: [PATCH 073/179] update --- outputPoints/dbOutputPointsHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/outputPoints/dbOutputPointsHandler.cpp b/outputPoints/dbOutputPointsHandler.cpp index 08a7cd47..3e17f7b1 100644 --- a/outputPoints/dbOutputPointsHandler.cpp +++ b/outputPoints/dbOutputPointsHandler.cpp @@ -220,7 +220,7 @@ bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &table setList += "'" + fieldName + "'="; int index = i * nrSoilLayers + layer - 1; - QString valueStr = QString::number(values[index], 'f', 2); + QString valueStr = QString::number(values[index], 'f', 3); setList += valueStr; if (index < (nrValues - 1)) From 6edf85e98f79311aaa16a67c0cf3e4f9469bd838 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 11 Jun 2024 20:24:25 +0200 Subject: [PATCH 074/179] update --- soil/soil.cpp | 6 +++--- soilWidget/tabHorizons.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soil/soil.cpp b/soil/soil.cpp index 87e42a3e..f461172d 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -752,7 +752,7 @@ namespace soil { double suctionStress = -waterPotential * getDegreeOfSaturation(); // [kPa] - double slopeAngle = asin(slope); + double slopeAngle = std::max(asin(slope), EPSILON); double frictionAngle = horizonPtr->frictionAngle * DEG_TO_RAD; double tanAngle = tan(slopeAngle); @@ -780,8 +780,8 @@ namespace soil // surface 2% if (upperDepth == 0.0) return 0.02; // first layer 1% - if (upperDepth > 0 && upperDepth < 0.5) return 0.01; - // sub-surface 0.5% + if (upperDepth > 0 && upperDepth < 0.4) return 0.01; + // sub-surface return MINIMUM_ORGANIC_MATTER; } diff --git a/soilWidget/tabHorizons.cpp b/soilWidget/tabHorizons.cpp index b5eeab52..3ea30816 100644 --- a/soilWidget/tabHorizons.cpp +++ b/soilWidget/tabHorizons.cpp @@ -334,7 +334,7 @@ bool TabHorizons::checkHorizonData(int horizonNum) tableDb->item(horizonNum,5)->setBackground(Qt::red); } - if (dbData->organicMatter != NODATA && (dbData->organicMatter < 0 || dbData->organicMatter > 100)) + if ( dbData->organicMatter != NODATA && ((dbData->organicMatter < 0) || (dbData->organicMatter > 100)) ) { tableDb->item(horizonNum,6)->setBackground(Qt::red); } From d8e832a735466b0c69dbdd057c58ef57034d000d Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 12 Jun 2024 17:10:23 +0200 Subject: [PATCH 075/179] update irrigation --- criteriaModel/criteria1DCase.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/criteriaModel/criteria1DCase.cpp b/criteriaModel/criteria1DCase.cpp index cd529c15..b2cdd326 100644 --- a/criteriaModel/criteria1DCase.cpp +++ b/criteriaModel/criteria1DCase.cpp @@ -298,15 +298,16 @@ bool Crit1DCase::computeNumericalFluxes(const Crit3DDate &myDate, std::string &e soilFluxes3D::initializeBalance(); // precipitation - // TODO improve for lat < 0 - int duration = 24; // [hours] winter - if (myDate.month >= 5 && myDate.month <= 9) + int precDuration = 24; // [hours] winter + if ( (meteoPoint.latitude > 0 && (myDate.month >= 5 && myDate.month <= 9)) + || (meteoPoint.latitude <= 0 && (myDate.month <= 3 || myDate.month >= 11)) ) { - duration = 12; // [hours] summer + precDuration = 12; // [hours] summer } - int precH0 = 13 - duration/2; - int precH1 = precH0 + duration -1; - double precFlux = (area * output.dailyPrec * 0.001) / (HOUR_SECONDS * duration); // [m3 s-1] + + int precH0 = 13 - precDuration/2; + int precH1 = precH0 + precDuration - 1; + double precFlux = (area * output.dailyPrec * 0.001) / (HOUR_SECONDS * precDuration); // [m3 s-1] // irrigation int irrH0 = 0; @@ -314,10 +315,17 @@ bool Crit1DCase::computeNumericalFluxes(const Crit3DDate &myDate, std::string &e double irrFlux = 0; if (! unit.isOptimalIrrigation && output.dailyIrrigation > 0) { - duration = int(output.dailyIrrigation / 3); // [hours] irrH0 = 6; // morning - irrH1 = irrH0 + duration -1; - irrFlux = (area * output.dailyIrrigation * 0.001) / (HOUR_SECONDS * duration); // [m3 s-1] + int maxDuration = 24 - irrH0 + 1; // [hours] + float mmHour = 3; + if (output.dailyIrrigation >= 10) + { + mmHour = 10; + } + int irrDuration = std::min(int(output.dailyIrrigation / mmHour), maxDuration); + + irrH1 = irrH0 + irrDuration - 1; + irrFlux = (area * output.dailyIrrigation * 0.001) / (HOUR_SECONDS * irrDuration); // [m3 s-1] } // daily cycle From de231c1f43587e38d57aece5dba35ded556d1613 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 12 Jun 2024 20:20:32 +0200 Subject: [PATCH 076/179] bare soil and update evaporation --- criteriaModel/carbonNitrogenModel.cpp | 6 +++-- criteriaModel/water1D.cpp | 30 ++++++++++++++++--------- crop/crop.cpp | 32 ++++++++++++++++++++++----- crop/crop.h | 5 ++++- crop/cropDbTools.cpp | 25 +++++++++++++-------- 5 files changed, 69 insertions(+), 29 deletions(-) diff --git a/criteriaModel/carbonNitrogenModel.cpp b/criteriaModel/carbonNitrogenModel.cpp index ba00e09d..cba020b7 100644 --- a/criteriaModel/carbonNitrogenModel.cpp +++ b/criteriaModel/carbonNitrogenModel.cpp @@ -1840,8 +1840,10 @@ void Crit1DCarbonNitrogenProfile::N_harvest(Crit1DCase &myCase) // public functi // N of leaves is incorporated in litter through the upeer layer with a smoothly rate during the leaf fall double N_toLitter = 0; - // !!! verificare USR PSR - if (myCase.crop.roots.firstRootLayer == 0 && myCase.crop.roots.lastRootLayer == 0) + + if ((myCase.crop.roots.firstRootLayer == 0 && myCase.crop.roots.lastRootLayer == 0) + || myCase.crop.roots.firstRootLayer == NODATA || myCase.crop.roots.lastRootLayer == NODATA + || myCase.crop.isBareSoil() ) return; for (int l = myCase.crop.roots.firstRootLayer; l <= myCase.crop.roots.lastRootLayer; l++) // verificare i cicli for per cambio indici diff --git a/criteriaModel/water1D.cpp b/criteriaModel/water1D.cpp index 8dd4c0f1..eea55e2c 100644 --- a/criteriaModel/water1D.cpp +++ b/criteriaModel/water1D.cpp @@ -373,8 +373,6 @@ double computeCapillaryRise(std::vector &soilLayers, double w double computeEvaporation(std::vector &soilLayers, double maxEvaporation) { - // TODO extend to geometric soilLayers - // surface evaporation double surfaceEvaporation = MINVALUE(maxEvaporation, soilLayers[0].waterContent); soilLayers[0].waterContent -= surfaceEvaporation; @@ -390,32 +388,43 @@ double computeEvaporation(std::vector &soilLayers, double max // soil evaporation int nrEvapLayers = int(floor(MAX_EVAPORATION_DEPTH / soilLayers[1].thickness)) +1; nrEvapLayers = std::min(nrEvapLayers, int(soilLayers.size()-1)); - double* coeffEvap = new double[nrEvapLayers]; - double layerDepth, coeffDepth; - double sumCoeff = 0; + std::vector coeffEvap; + coeffEvap.resize(nrEvapLayers); + double minDepth = soilLayers[1].depth + soilLayers[1].thickness / 2; + double sumCoeff = 0; for (int i=1; i <= nrEvapLayers; i++) { - layerDepth = soilLayers[i].depth + soilLayers[i].thickness / 2.0; + double layerDepth = soilLayers[i].depth + soilLayers[i].thickness / 2.0; - coeffDepth = MAXVALUE((layerDepth - minDepth) / (MAX_EVAPORATION_DEPTH - minDepth), 0); + double coeffDepth = MAXVALUE((layerDepth - minDepth) / (MAX_EVAPORATION_DEPTH - minDepth), 0); // evaporation coefficient: 1 at depthMin, ~0.1 at MAX_EVAPORATION_DEPTH coeffEvap[i-1] = exp(-2 * coeffDepth); sumCoeff += coeffEvap[i-1]; } + // normalize + std::vector coeffThreshold; + coeffThreshold.resize(nrEvapLayers); + for (int i=0; i < nrEvapLayers; i++) + { + coeffThreshold[i] = (1.0 - coeffEvap[i]) * 0.5; + coeffEvap[i] /= sumCoeff; + } + bool isWaterSupply = true; double sumEvap, evapLayerThreshold, evapLayer; - while ((residualEvaporation > EPSILON) && (isWaterSupply == true)) + int nrIteration = 0; + while ((residualEvaporation > EPSILON) && (isWaterSupply == true) && nrIteration < 3) { sumEvap = 0.0; for (int i=1; i <= nrEvapLayers; i++) { evapLayer = residualEvaporation * (coeffEvap[i-1] / sumCoeff); - evapLayerThreshold = soilLayers[i].HH + (1 - coeffEvap[i-1]) * (soilLayers[i].FC - soilLayers[i].HH); + evapLayerThreshold = soilLayers[i].HH + (soilLayers[i].FC - soilLayers[i].HH) * coeffThreshold[i-1]; if (soilLayers[i].waterContent > (evapLayerThreshold + evapLayer)) { @@ -441,10 +450,9 @@ double computeEvaporation(std::vector &soilLayers, double max residualEvaporation -= sumEvap; actualEvaporation += sumEvap; + nrIteration++; } - delete[] coeffEvap; - return actualEvaporation; } diff --git a/crop/crop.cpp b/crop/crop.cpp index ba743041..b71fc6bf 100644 --- a/crop/crop.cpp +++ b/crop/crop.cpp @@ -107,21 +107,36 @@ void Crit3DCrop::initialize(double latitude, unsigned int nrLayers, double total // initialize root depth roots.rootDepth = 0; - if (totalSoilDepth == 0 || roots.rootDepthMax < totalSoilDepth) - roots.actualRootDepthMax = roots.rootDepthMax; + if (isBareSoil()) + { + roots.rootDepthMax = 0; + roots.actualRootDepthMax = 0; + } else - roots.actualRootDepthMax = totalSoilDepth; + { + if (totalSoilDepth == 0 || roots.rootDepthMax < totalSoilDepth) + { + roots.actualRootDepthMax = roots.rootDepthMax; + } + else + { + roots.actualRootDepthMax = totalSoilDepth; + } + } degreeDays = 0; if (latitude > 0) + { doyStartSenescence = 305; + } else + { doyStartSenescence = 120; + } LAIstartSenescence = NODATA; currentSowingDoy = NODATA; - daysSinceIrrigation = NODATA; // check if the crop is living @@ -134,7 +149,7 @@ void Crit3DCrop::initialize(double latitude, unsigned int nrLayers, double total } else { - isLiving = true; + isLiving = !isBareSoil(); } resetCrop(nrLayers); @@ -399,7 +414,7 @@ bool Crit3DCrop::needReset(Crit3DDate myDate, double latitude, double waterTable void Crit3DCrop::resetCrop(unsigned int nrLayers) { // roots - if (! isRootStatic()) + if (! isBareSoil() && ! isRootStatic()) { for (unsigned int i = 0; i < nrLayers; i++) roots.rootDensity[i] = 0; @@ -855,10 +870,13 @@ speciesType getCropType(std::string cropType) return FALLOW_ANNUAL; else if (cropType == "tree" || cropType == "fruit_tree") return TREE; + else if (cropType == "bare" || cropType == "bare_soil") + return BARESOIL; else return HERBACEOUS_ANNUAL; } + std::string getCropTypeString(speciesType cropType) { switch (cropType) @@ -877,6 +895,8 @@ std::string getCropTypeString(speciesType cropType) return "fallow_annual"; case TREE: return "tree"; + case BARESOIL: + return "bare_soil"; } return "No crop type"; diff --git a/crop/crop.h b/crop/crop.h index 13dc588a..68c81dbe 100644 --- a/crop/crop.h +++ b/crop/crop.h @@ -11,7 +11,7 @@ #include "root.h" #endif - enum speciesType {HERBACEOUS_ANNUAL, HERBACEOUS_PERENNIAL, HORTICULTURAL, GRASS, TREE, FALLOW, FALLOW_ANNUAL}; + enum speciesType {HERBACEOUS_ANNUAL, HERBACEOUS_PERENNIAL, HORTICULTURAL, GRASS, TREE, FALLOW, FALLOW_ANNUAL, BARESOIL}; #define NR_CROP_SPECIES 7 /*! @@ -81,6 +81,9 @@ bool isSowingCrop() const; bool isRootStatic() const; + bool isBareSoil() const + { return (type == BARESOIL); } + double getDailyDegreeIncrease(double tmin, double tmax, int doy); void initialize(double latitude, unsigned int nrLayers, double totalSoilDepth, int currentDoy); diff --git a/crop/cropDbTools.cpp b/crop/cropDbTools.cpp index 6904172b..6a23cee4 100644 --- a/crop/cropDbTools.cpp +++ b/crop/cropDbTools.cpp @@ -87,19 +87,18 @@ bool loadCropParameters(const QSqlDatabase &dbCrop, QString idCrop, Crit3DCrop & myCrop.kcMax = query.value("kc_max").toDouble(); // [cm] if (! getValue(query.value("psi_leaf"), &(myCrop.psiLeaf))) + { + // default myCrop.psiLeaf = 16000; + } myCrop.stressTolerance = query.value("stress_tolerance").toDouble(); // fraction of Readily Available Water if (! getValue(query.value("raw_fraction"), &(myCrop.fRAW))) { - // old version - if (! getValue(query.value("frac_read_avail_water_max"), &(myCrop.fRAW))) - { - errorStr = "Missing RAW_fraction for crop: " + idCropString; - return false; - } + // default + myCrop.fRAW = 0.6; } // IRRIGATION @@ -109,17 +108,25 @@ bool loadCropParameters(const QSqlDatabase &dbCrop, QString idCrop, Crit3DCrop & getValue(query.value("doy_start_irrigation"), &(myCrop.doyStartIrrigation)); getValue(query.value("doy_end_irrigation"), &(myCrop.doyEndIrrigation)); - // key value for irrigation + // irrigation volume [mm day-1] if (! getValue(query.value("irrigation_volume"), &(myCrop.irrigationVolume))) + { + // default: no irrigation myCrop.irrigationVolume = 0; + } // LAI grass if (! getValue(query.value("lai_grass"), &(myCrop.LAIgrass))) + { myCrop.LAIgrass = 0; + } - // max surface puddle + // max surface puddle [mm] if (! getValue(query.value("max_height_surface_puddle"), &(myCrop.maxSurfacePuddle))) - myCrop.maxSurfacePuddle = 0; + { + // default: 5 mm + myCrop.maxSurfacePuddle = 5; + } return true; } From 3d44ea85f494532ddff96814a27cd8b457c62676 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 13 Jun 2024 14:56:46 +0200 Subject: [PATCH 077/179] bare soil --- criteria1DWidget/criteria1DWidget.cpp | 12 ++- criteriaModel/criteria1DProject.cpp | 19 ++-- crop/crop.cpp | 2 +- crop/cropDbTools.cpp | 125 ++++++++++++++++++++------ 4 files changed, 115 insertions(+), 43 deletions(-) diff --git a/criteria1DWidget/criteria1DWidget.cpp b/criteria1DWidget/criteria1DWidget.cpp index 627a0ae8..c6eadb70 100644 --- a/criteria1DWidget/criteria1DWidget.cpp +++ b/criteria1DWidget/criteria1DWidget.cpp @@ -594,6 +594,7 @@ void Criteria1DWidget::on_actionOpenProject() this->lastYearListComboBox.blockSignals(false); openComputationUnitsDB(myProject.dbComputationUnitsName); + viewMenu->setEnabled(true); if (soilListComboBox.count() == 0) { @@ -1053,15 +1054,20 @@ void Criteria1DWidget::on_actionChooseCase() // METEO meteoListComboBox.setCurrentText(myProject.myCase.unit.idMeteo); - // CROP + // CROP ID myProject.myCase.unit.idCrop = getIdCropFromClass(myProject.dbCrop, "crop_class", "id_class", myProject.myCase.unit.idCropClass, errorStr); - if (myProject.myCase.unit.idCrop != "") + if (myProject.myCase.unit.idCrop == "") + { + // it is a single crop, not a crop class + myProject.myCase.unit.idCrop = myProject.myCase.unit.idCropClass; + } + if ( cropListComboBox.findText(myProject.myCase.unit.idCrop) != -1 ) { cropListComboBox.setCurrentText(myProject.myCase.unit.idCrop); } else { - QMessageBox::critical(nullptr, "Error!", "Missing crop class: " + myProject.myCase.unit.idCropClass + "\n" + errorStr); + QMessageBox::critical(nullptr, "Error!", "Missing crop: " + myProject.myCase.unit.idCropClass + "\n" + errorStr); } // SOIL diff --git a/criteriaModel/criteria1DProject.cpp b/criteriaModel/criteria1DProject.cpp index 68c6de56..50bc5816 100644 --- a/criteriaModel/criteria1DProject.cpp +++ b/criteriaModel/criteria1DProject.cpp @@ -1095,7 +1095,11 @@ int Crit1DProject::computeAllUnits() } } - int infoStep = std::max(1, int(compUnitList.size() / 20)); + int infoStep = compUnitList.size(); + if (compUnitList.size() >= 20) + { + infoStep = int(compUnitList.size() / 20); + } logger.writeInfo("COMPUTE..."); try @@ -1108,25 +1112,20 @@ int Crit1DProject::computeAllUnits() logger.writeInfo(compUnitList[i].idCase + " - numerical computation..."); } - // CROP + // check if it is crop class compUnitList[i].idCrop = getIdCropFromClass(dbCrop, "crop_class", "id_class", compUnitList[i].idCropClass, projectError); if (compUnitList[i].idCrop == "") { - logger.writeInfo("Unit " + compUnitList[i].idCase + " " + compUnitList[i].idCropClass + " ***** missing CROP *****"); - isErrorCrop = true; - continue; + compUnitList[i].idCrop = compUnitList[i].idCropClass; } // IRRI_RATIO float irriRatio = getIrriRatioFromCropClass(dbCrop, "crop_class", "id_class", compUnitList[i].idCropClass, projectError); - - if ((isYearlyStatistics || isMonthlyStatistics || isSeasonalForecast || isEnsembleForecast || isShortTermForecast) - && (int(irriRatio) == int(NODATA))) + if (isEqual(irriRatio, NODATA)) { - logger.writeInfo("Unit " + compUnitList[i].idCase + " " + compUnitList[i].idCropClass + " ***** missing IRRIGATION RATIO *****"); - continue; + irriRatio = 1; } // SOIL diff --git a/crop/crop.cpp b/crop/crop.cpp index b71fc6bf..d89405dc 100644 --- a/crop/crop.cpp +++ b/crop/crop.cpp @@ -2,7 +2,7 @@ \file crop.cpp \abstract - Crop class functions + Crop development (Crit3DCrop class) \authors Fausto Tomei ftomei@arpae.it diff --git a/crop/cropDbTools.cpp b/crop/cropDbTools.cpp index 6a23cee4..2bf3b7be 100644 --- a/crop/cropDbTools.cpp +++ b/crop/cropDbTools.cpp @@ -163,31 +163,69 @@ bool updateCropLAIparam(QSqlDatabase &dbCrop, const Crit3DCrop &myCrop, QString "lai_curve_factor_a = :lai_curve_factor_a, lai_curve_factor_b = :lai_curve_factor_b, " "kc_max = :kc_max WHERE id_crop = :id_crop"); - if (myCrop.sowingDoy != NODATA) + if (myCrop.isBareSoil()) { - qry.bindValue(":sowing_doy", myCrop.sowingDoy); - qry.bindValue(":max_cycle", myCrop.plantCycle); + qry.bindValue(":sowing_doy", ""); + qry.bindValue(":max_cycle", ""); + qry.bindValue(":lai_grass", ""); + qry.bindValue(":lai_min", ""); + qry.bindValue(":lai_max", ""); + qry.bindValue(":thermal_threshold", ""); + qry.bindValue(":upper_thermal_threshold", ""); + qry.bindValue(":degree_days_lai_increase", ""); + qry.bindValue(":degree_days_lai_decrease", ""); + qry.bindValue(":lai_curve_factor_a", ""); + qry.bindValue(":lai_curve_factor_b", ""); + qry.bindValue(":kc_max", ""); } else { - qry.bindValue(":sowing_doy", ""); - qry.bindValue(":max_cycle", 365); + if (myCrop.sowingDoy != NODATA) + { + qry.bindValue(":sowing_doy", myCrop.sowingDoy); + qry.bindValue(":max_cycle", myCrop.plantCycle); + } + else + { + qry.bindValue(":sowing_doy", ""); + qry.bindValue(":max_cycle", 365); + } + + if (myCrop.LAIgrass != NODATA) + { + qry.bindValue(":lai_grass", myCrop.LAIgrass); + } + else + { + qry.bindValue(":lai_grass", ""); + } + + if (myCrop.degreeDaysEmergence != 0 && myCrop.degreeDaysEmergence != NODATA) + { + qry.bindValue(":degree_days_emergence", myCrop.degreeDaysEmergence); + } + else + { + qry.bindValue(":degree_days_emergence", ""); + } + + qry.bindValue(":lai_min", myCrop.LAImin); + qry.bindValue(":lai_max", myCrop.LAImax); + + qry.bindValue(":thermal_threshold", myCrop.thermalThreshold); + qry.bindValue(":upper_thermal_threshold", myCrop.upperThermalThreshold); + + qry.bindValue(":degree_days_lai_increase", myCrop.degreeDaysIncrease); + qry.bindValue(":degree_days_lai_decrease", myCrop.degreeDaysDecrease); + + qry.bindValue(":lai_curve_factor_a", myCrop.LAIcurve_a); + qry.bindValue(":lai_curve_factor_b", myCrop.LAIcurve_b); + qry.bindValue(":kc_max", myCrop.kcMax); } - qry.bindValue(":lai_min", myCrop.LAImin); - qry.bindValue(":lai_max", myCrop.LAImax); - qry.bindValue(":lai_grass", myCrop.LAIgrass); - qry.bindValue(":thermal_threshold", myCrop.thermalThreshold); - qry.bindValue(":upper_thermal_threshold", myCrop.upperThermalThreshold); - qry.bindValue(":degree_days_emergence", myCrop.degreeDaysEmergence); - qry.bindValue(":degree_days_lai_increase", myCrop.degreeDaysIncrease); - qry.bindValue(":degree_days_lai_decrease", myCrop.degreeDaysDecrease); - qry.bindValue(":lai_curve_factor_a", myCrop.LAIcurve_a); - qry.bindValue(":lai_curve_factor_b", myCrop.LAIcurve_b); - qry.bindValue(":kc_max", myCrop.kcMax); qry.bindValue(":id_crop", QString::fromStdString(myCrop.idCrop)); - if( !qry.exec() ) + if( ! qry.exec() ) { errorStr = qry.lastError().text(); return false; @@ -207,11 +245,30 @@ bool updateCropRootparam(QSqlDatabase &dbCrop, const Crit3DCrop &myCrop, QString " degree_days_root_increase = :degree_days_root_increase" " WHERE id_crop = :id_crop"); - qry.bindValue(":root_shape", root::getRootDistributionNumber(myCrop.roots.rootShape)); - qry.bindValue(":root_depth_zero", myCrop.roots.rootDepthMin); - qry.bindValue(":root_depth_max", myCrop.roots.rootDepthMax); - qry.bindValue(":root_shape_deformation", myCrop.roots.shapeDeformation); - qry.bindValue(":degree_days_root_increase", myCrop.roots.degreeDaysRootGrowth); + if (myCrop.isBareSoil()) + { + qry.bindValue(":root_shape", ""); + qry.bindValue(":root_depth_zero", ""); + qry.bindValue(":root_depth_max", ""); + qry.bindValue(":root_shape_deformation", ""); + qry.bindValue(":degree_days_root_increase", ""); + } + else + { + qry.bindValue(":root_shape", root::getRootDistributionNumber(myCrop.roots.rootShape)); + qry.bindValue(":root_depth_zero", myCrop.roots.rootDepthMin); + qry.bindValue(":root_depth_max", myCrop.roots.rootDepthMax); + qry.bindValue(":root_shape_deformation", myCrop.roots.shapeDeformation); + + if (myCrop.roots.degreeDaysRootGrowth != NODATA) + { + qry.bindValue(":degree_days_root_increase", myCrop.roots.degreeDaysRootGrowth); + } + else + { + qry.bindValue(":degree_days_root_increase", ""); + } + } qry.bindValue(":id_crop", QString::fromStdString(myCrop.idCrop)); @@ -220,6 +277,7 @@ bool updateCropRootparam(QSqlDatabase &dbCrop, const Crit3DCrop &myCrop, QString errorStr = qry.lastError().text(); return false; } + return true; } @@ -233,12 +291,12 @@ bool updateCropIrrigationparam(QSqlDatabase &dbCrop, const Crit3DCrop &myCrop, Q "psi_leaf = :psi_leaf, raw_fraction = :raw_fraction, stress_tolerance = :stress_tolerance" " WHERE id_crop = :id_crop"); - if (myCrop.irrigationVolume == 0) + if (myCrop.irrigationVolume == 0 || myCrop.isBareSoil()) { - qry.bindValue(":irrigation_shift", QVariant(QVariant::String)); + qry.bindValue(":irrigation_shift", ""); qry.bindValue(":irrigation_volume", 0); - qry.bindValue(":degree_days_start_irrigation", QVariant(QVariant::String)); - qry.bindValue(":degree_days_end_irrigation", QVariant(QVariant::String)); + qry.bindValue(":degree_days_start_irrigation", ""); + qry.bindValue(":degree_days_end_irrigation", ""); } else { @@ -248,9 +306,18 @@ bool updateCropIrrigationparam(QSqlDatabase &dbCrop, const Crit3DCrop &myCrop, Q qry.bindValue(":degree_days_end_irrigation", myCrop.degreeDaysEndIrrigation); } - qry.bindValue(":psi_leaf", myCrop.psiLeaf); - qry.bindValue(":raw_fraction", myCrop.fRAW); - qry.bindValue(":stress_tolerance", myCrop.stressTolerance); + if (myCrop.isBareSoil() ) + { + qry.bindValue(":psi_leaf", ""); + qry.bindValue(":raw_fraction", ""); + qry.bindValue(":stress_tolerance", ""); + } + else + { + qry.bindValue(":psi_leaf", myCrop.psiLeaf); + qry.bindValue(":raw_fraction", myCrop.fRAW); + qry.bindValue(":stress_tolerance", myCrop.stressTolerance); + } qry.bindValue(":id_crop", QString::fromStdString(myCrop.idCrop)); From 55d7577724d39a2ac8aef97e782e6905eb70ae20 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 14 Jun 2024 17:44:01 +0200 Subject: [PATCH 078/179] update evaporation --- criteriaModel/water1D.cpp | 2 +- criteriaModel/water1D.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/criteriaModel/water1D.cpp b/criteriaModel/water1D.cpp index eea55e2c..fd4ade3e 100644 --- a/criteriaModel/water1D.cpp +++ b/criteriaModel/water1D.cpp @@ -417,7 +417,7 @@ double computeEvaporation(std::vector &soilLayers, double max bool isWaterSupply = true; double sumEvap, evapLayerThreshold, evapLayer; int nrIteration = 0; - while ((residualEvaporation > EPSILON) && (isWaterSupply == true) && nrIteration < 3) + while ((residualEvaporation > EPSILON) && (isWaterSupply == true) && nrIteration < 5) { sumEvap = 0.0; diff --git a/criteriaModel/water1D.h b/criteriaModel/water1D.h index af41c5c0..4c566d75 100644 --- a/criteriaModel/water1D.h +++ b/criteriaModel/water1D.h @@ -7,7 +7,7 @@ #include "soil.h" #endif - #define MAX_EVAPORATION_DEPTH 0.2 + #define MAX_EVAPORATION_DEPTH 0.25 class Crit3DCrop; From 7239de916b69a7a7ef3f88ca8855b342d600dcbd Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Mon, 17 Jun 2024 12:37:35 +0200 Subject: [PATCH 079/179] changed multiple detrending and fixed bug --- interpolation/interpolation.cpp | 15 ++--- mathFunctions/furtherMathFunctions.cpp | 82 ++++++++++++++++++++++++-- project/project.cpp | 2 - 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 046a38a1..a93fa14d 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -933,7 +933,7 @@ float modifiedShepardIdw(vector &myPoints, { t[i] = 0; for (j=0; j < validPoints.size(); j++) - if (i != j && S[i] > 0) + if (i != j && S[i] > 0 && validPoints[i].distance > 0 && validPoints[j].distance > 0) { cosine = ((X - (float)validPoints[i].point->utm.x) * (X - (float)validPoints[j].point->utm.x) + (Y - (float)validPoints[i].point->utm.y) * (Y - (float)validPoints[j].point->utm.y)) / (validPoints[i].distance * validPoints[j].distance); t[i] = t[i] + S[j] * (1 - cosine); @@ -1060,8 +1060,9 @@ void localSelection(vector &inputPoints, vector < r1 += stepRadius; } - for (i=0; i< selectedPoints.size(); i++) - selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / maxDistance,2*EPSILON); + if (maxDistance != 0) + for (i=0; i< selectedPoints.size(); i++) + selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (maxDistance*maxDistance*maxDistance),EPSILON); mySettings.setLocalRadius(maxDistance); } @@ -1357,7 +1358,7 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati { mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 0, -0.006, 1800, max+2, 0.01, 0}; + tempParam = {-200, min-2, 0.001, -0.006, 1800, max+2, 0.01, 0.0015}; else { tempParam = mySettings->getProxy(i)->getFittingParametersRange(); @@ -1369,7 +1370,7 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 100, 0.001, -0.006, -0.006, 1800, max+2, 1000, 0.007, 0, 0}; + tempParam = {-200, min-2, 100, 0.001, -0.006, -0.006, 1800, max+2, 1000, 0.007, 0.0015, 0.0015}; else { tempParam = mySettings->getProxy(i)->getFittingParametersRange(); @@ -1381,7 +1382,7 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 100, 0.001, -0.006, 1800, max+2, 1000, 0.007, 0}; + tempParam = {-200, min-2, 100, 0.001, -0.006, 1800, max+2, 1000, 0.007, 0.0015}; else { tempParam = mySettings->getProxy(i)->getFittingParametersRange(); @@ -1803,7 +1804,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st //std::vector > parameters; std::vector&)>> myFunc; - unsigned int nrMaxStep = 20; + unsigned int nrMaxStep = 100; if (parameters.empty()) nrMaxStep *= 10; diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 8127390c..e54a1b74 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -1971,7 +1971,7 @@ namespace interpolation std::vector ySim(nrData); int counter = 0; - //srand (unsigned(time(nullptr))); + /*srand (unsigned(time(nullptr))); std::random_device rd; std::mt19937 gen(rd()); std::normal_distribution normal_dis(0.5, 0.5); @@ -1989,9 +1989,80 @@ namespace interpolation discreteParameters.push_back(tempDiscrete); tempDiscrete.clear(); + }*/ + + //grigliato + + std::vector steps; + if (parameters.size() == 4) + steps = {50.0, 0.5, 0.00075, 0.00075}; + else if (parameters.size() == 6) + steps = {50.0, 0.5, 50.0, 0.00075, 0.00075, 0.00075}; + else return false; + + const int numSteps = 40; + int directions[] = {1, -1}; + int numParamsToVary = parameters.size(); + std::vector firstGuessParam = parameters; + + for (int step = 1; step <= numSteps; ++step) + { + for (int dir = 0; dir < 2; ++dir) + { + for (int paramIndex = 0; paramIndex < numParamsToVary; ++paramIndex) + { + + fittingMarquardt_nDimension_noSquares_singleFunction(func,parametersMin, + parametersMax,parameters, + parametersDelta,maxIterationsNr, + myEpsilon,x,y,weights); + + for (i=0;i (bestR2-deltaR2)) + { + for (j=0;j (bestR2)) + { + for (j=0; j nrTrials) || ((R2Previous[0] != NODATA) && fabs(R2Previous[0]-R2Previous[nrMinima-1]) < deltaR2 )) + break; + + } + //end grigliato - do + //random + /*do { fittingMarquardt_nDimension_noSquares_singleFunction(func,parametersMin, parametersMax,parameters, @@ -2030,13 +2101,13 @@ namespace interpolation } counter++; - /*for (j=0; j= 1.0); parameters[j] = parametersMin[j] + (truncNormal)*(parametersMax[j]-parametersMin[j]); - }*/ + } int indice = 0; for (j=0; j= discreteParameters[j].size()); parameters[j] = discreteParameters[j][indice]; } - } while( (counter < nrTrials) && !(R2Previous[0] > 0.797 && R2Previous[nrMinima-1] > 0.8) && ((R2Previous[0] == NODATA) || fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2 )); + } while( (counter < nrTrials) && !(R2Previous[0] > 0.797 && R2Previous[nrMinima-1] > 0.8) && ((R2Previous[0] == NODATA) || fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2 )); +*/ for (j=0; jvalue[row][col] = interpolate(subsetInterpolationPoints, &interpolationSettings, meteoSettings, myVar, x, y, z, proxyValues, true); - myRaster->setParametersForRowCol(row, col, interpolationSettings.getFittingParameters()); interpolationSettings.setCurrentCombination(interpolationSettings.getSelectedCombination()); } From 3e2fca506e44caafd43da921b5c818b6ea291251 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 17 Jun 2024 16:24:45 +0200 Subject: [PATCH 080/179] max evap depth moved to constants --- criteriaModel/water1D.cpp | 2 +- criteriaModel/water1D.h | 2 -- mathFunctions/commonConstants.h | 3 +++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/criteriaModel/water1D.cpp b/criteriaModel/water1D.cpp index fd4ade3e..ad12d796 100644 --- a/criteriaModel/water1D.cpp +++ b/criteriaModel/water1D.cpp @@ -399,7 +399,7 @@ double computeEvaporation(std::vector &soilLayers, double max double layerDepth = soilLayers[i].depth + soilLayers[i].thickness / 2.0; double coeffDepth = MAXVALUE((layerDepth - minDepth) / (MAX_EVAPORATION_DEPTH - minDepth), 0); - // evaporation coefficient: 1 at depthMin, ~0.1 at MAX_EVAPORATION_DEPTH + // evaporation coefficient: 1 at depthMin, ~0.1 at maximum depth for evaporation coeffEvap[i-1] = exp(-2 * coeffDepth); sumCoeff += coeffEvap[i-1]; diff --git a/criteriaModel/water1D.h b/criteriaModel/water1D.h index 4c566d75..074e70fb 100644 --- a/criteriaModel/water1D.h +++ b/criteriaModel/water1D.h @@ -7,8 +7,6 @@ #include "soil.h" #endif - #define MAX_EVAPORATION_DEPTH 0.25 - class Crit3DCrop; void initializeWater(std::vector &soilLayers); diff --git a/mathFunctions/commonConstants.h b/mathFunctions/commonConstants.h index 13090068..1342b496 100644 --- a/mathFunctions/commonConstants.h +++ b/mathFunctions/commonConstants.h @@ -92,6 +92,9 @@ #define MEAN_GEOMETRIC 0 #define MEAN_LOGARITHMIC 1 + // maximum soil depth for evaporation computation [m] + #define MAX_EVAPORATION_DEPTH 0.25 + //#define BOUNDARY_SURFACE 1 #define BOUNDARY_RUNOFF 2 #define BOUNDARY_FREEDRAINAGE 3 From 6d51b86b8dd1238669352254bcaeb511440ba90d Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 17 Jun 2024 18:52:10 +0200 Subject: [PATCH 081/179] fix crop transpiration --- crop/root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crop/root.cpp b/crop/root.cpp index dbf77110..3eb4ad0a 100644 --- a/crop/root.cpp +++ b/crop/root.cpp @@ -497,7 +497,7 @@ namespace root const std::vector &layerDepth, const std::vector &layerThickness) { // check soil - if (nrLayers == 0) + if (nrLayers <= 1) { myCrop.roots.firstRootLayer = NODATA; myCrop.roots.lastRootLayer = NODATA; From 1df66f9c821ef9d2e3ce4e162b2be32d8e9cba9c Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 17 Jun 2024 19:21:55 +0200 Subject: [PATCH 082/179] update 1D --- criteriaModel/criteria1DProject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/criteriaModel/criteria1DProject.cpp b/criteriaModel/criteria1DProject.cpp index 50bc5816..a3e074d4 100644 --- a/criteriaModel/criteria1DProject.cpp +++ b/criteriaModel/criteria1DProject.cpp @@ -1095,7 +1095,7 @@ int Crit1DProject::computeAllUnits() } } - int infoStep = compUnitList.size(); + int infoStep = int(compUnitList.size()); if (compUnitList.size() >= 20) { infoStep = int(compUnitList.size() / 20); @@ -1170,7 +1170,7 @@ int Crit1DProject::computeAllUnits() } } - if ((i+1) % infoStep == 0 && nrUnitsComputed > 0) + if ((i+1) % infoStep == 0 && nrUnitsComputed > 20) { double percentage = (i+1) * 100.0 / compUnitList.size(); logger.writeInfo("..." + QString::number(round(percentage)) + "%"); From 782adc3c349b3a3d1235c16b49911bdb89fc89fe Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 18 Jun 2024 15:49:49 +0200 Subject: [PATCH 083/179] add crop unit table --- crop/crop.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crop/crop.h b/crop/crop.h index 68c81dbe..29c32389 100644 --- a/crop/crop.h +++ b/crop/crop.h @@ -43,8 +43,8 @@ /*! * water need */ - double kcMax; /*!< [-] */ - int psiLeaf; /*!< [cm] */ + double kcMax; /*!< [-] maximum crop coefficient */ + int psiLeaf; /*!< [cm] maximum water suction potential */ double stressTolerance; /*!< [-] */ double fRAW; /*!< [-] fraction of Readily Available Water */ From d370af1250dd58e72c243fe748c583645bd48dc2 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 18 Jun 2024 17:08:41 +0200 Subject: [PATCH 084/179] fix open wrong meteoPointsDb --- project/project.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index c818c219..034b31b9 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -1105,8 +1105,6 @@ bool Project::loadMeteoPointsDB(QString fileName) closeMeteoPointsDB(); - logInfoGUI("Load meteo points DB: " + fileName); - dbPointsFileName = fileName; QString dbName = getCompleteFileName(fileName, PATH_METEOPOINT); if (! QFile(dbName).exists()) @@ -1118,7 +1116,7 @@ bool Project::loadMeteoPointsDB(QString fileName) meteoPointsDbHandler = new Crit3DMeteoPointsDbHandler(dbName); if (! meteoPointsDbHandler->getErrorString().isEmpty()) { - errorString = "Function loadMeteoPointsDB:\n" + dbName + "\n" + meteoPointsDbHandler->getErrorString(); + errorString = meteoPointsDbHandler->getErrorString(); closeMeteoPointsDB(); return false; } @@ -1194,7 +1192,6 @@ bool Project::loadMeteoPointsDB(QString fileName) meteoPointsLoaded = true; logInfo("Meteo points DB = " + dbName); - closeLogInfo(); return true; } From 421360d1f97a52833d458e6a4e69579c34a6c8fb Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 18 Jun 2024 17:38:12 +0200 Subject: [PATCH 085/179] fix download point properties arkimet --- dbMeteoPoints/download.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbMeteoPoints/download.cpp b/dbMeteoPoints/download.cpp index c0eb5e46..379d6919 100644 --- a/dbMeteoPoints/download.cpp +++ b/dbMeteoPoints/download.cpp @@ -55,7 +55,7 @@ bool Download::getPointProperties(QList datasetList) qDebug() << "err: " << error->errorString() << " -> " << error->offset; // check validity of the document - if(!doc.isNull() && doc.isArray()) + if(! doc.isNull() && doc.isArray() ) { QJsonArray jsonArr = doc.array(); @@ -71,7 +71,7 @@ bool Download::getPointProperties(QList datasetList) qDebug() << "jsonDataset: value is not string"; else foreach(QString item, _datasetsList) - if (jsonDataset == item) + if (jsonDataset.toString().toUpper() == item.toUpper()) { this->downloadMetadata(obj); } From 1128b489c8dbd08d5707d2467a9f0bc7c679eef6 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 19 Jun 2024 12:41:30 +0200 Subject: [PATCH 086/179] update 3D --- project/project.cpp | 25 +++++++++++++++++++++++++ project/project.h | 7 ++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/project/project.cpp b/project/project.cpp index 034b31b9..1d6a1fe2 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4459,6 +4459,31 @@ void Project::logError(QString myStr) } +void Project::logWarning(QString myStr) +{ + errorString = myStr; + logWarning(); +} + + +void Project::logWarning() +{ + if (logFile.is_open()) + { + logFile << "WARNING! " << errorString.toStdString() << std::endl; + } + + if (modality == MODE_GUI) + { + QMessageBox::warning(nullptr, "WARNING!", errorString); + } + else + { + std::cout << "WARNING! " << errorString.toStdString() << std::endl; + } +} + + void Project::logError() { if (logFile.is_open()) diff --git a/project/project.h b/project/project.h index a2757c0c..c8ef74d5 100644 --- a/project/project.h +++ b/project/project.h @@ -203,12 +203,17 @@ QString getCompleteFileName(QString fileName, QString secondaryPath); bool setLogFile(QString myFileName); - void logError(QString myStr); + void logInfo(QString myStr); void logInfoGUI(QString myStr); void closeLogInfo(); + + void logError(QString myStr); void logError(); + void logWarning(QString myStr); + void logWarning(); + int setProgressBar(QString myStr, int nrValues); void updateProgressBar(int value); void updateProgressBarText(QString myStr); From 37eb481c27ea981bffeff732f1f44cd720a37284 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 19 Jun 2024 18:40:26 +0200 Subject: [PATCH 087/179] load water state --- soilFluxes3D/header/soilFluxes3D.h | 2 +- soilFluxes3D/soilFluxes3D.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soilFluxes3D/header/soilFluxes3D.h b/soilFluxes3D/header/soilFluxes3D.h index 5f509a39..7341310c 100644 --- a/soilFluxes3D/header/soilFluxes3D.h +++ b/soilFluxes3D/header/soilFluxes3D.h @@ -51,7 +51,7 @@ // WATER __EXTERN int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, int conductivityMeanType, float horizVertRatioConductivity); __EXTERN int DLL_EXPORT __STDCALL setWaterContent(long index, double myWaterContent); - __EXTERN int DLL_EXPORT __STDCALL setMatricPotential(long index, double potential); + __EXTERN int DLL_EXPORT __STDCALL setMatricPotential(long index, double psi); __EXTERN int DLL_EXPORT __STDCALL setTotalPotential(long index, double totalPotential); __EXTERN int DLL_EXPORT __STDCALL setPrescribedTotalPotential(long index, double prescribedTotalPotential); __EXTERN int DLL_EXPORT __STDCALL setWaterSinkSource(long index, double sinkSource); diff --git a/soilFluxes3D/soilFluxes3D.cpp b/soilFluxes3D/soilFluxes3D.cpp index 402fa5f0..ba552106 100644 --- a/soilFluxes3D/soilFluxes3D.cpp +++ b/soilFluxes3D/soilFluxes3D.cpp @@ -434,17 +434,17 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief setMatricPotential * \param nodeIndex - * \param potential [m] + * \param psi [m] * \return OK/ERROR */ - int DLL_EXPORT __STDCALL setMatricPotential(long nodeIndex, double potential) + int DLL_EXPORT __STDCALL setMatricPotential(long nodeIndex, double psi) { if (nodeListPtr == nullptr) return MEMORY_ERROR; if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) return INDEX_ERROR; - nodeListPtr[nodeIndex].H = potential + nodeListPtr[nodeIndex].z; + nodeListPtr[nodeIndex].H = psi + nodeListPtr[nodeIndex].z; nodeListPtr[nodeIndex].oldH = nodeListPtr[nodeIndex].H; if (nodeListPtr[nodeIndex].isSurface) From d5c00223a28a392953cbad1313ff9bf83447a7d4 Mon Sep 17 00:00:00 2001 From: cate-to Date: Thu, 20 Jun 2024 14:12:47 +0200 Subject: [PATCH 088/179] added altitude weights for elevation only in multiple detrending --- interpolation/interpolation.cpp | 68 ++++++++++---------------- interpolation/interpolation.h | 2 +- interpolation/interpolationPoint.h | 1 + mathFunctions/furtherMathFunctions.cpp | 2 +- project/project.cpp | 6 +-- proxyWidget/localProxyWidget.cpp | 4 +- proxyWidget/localProxyWidget.h | 1 + 7 files changed, 34 insertions(+), 50 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index a93fa14d..dacaf920 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1017,7 +1017,7 @@ float gaussWeighted(vector &myPointList) // TODO elevation std dev? void localSelection(vector &inputPoints, vector &selectedPoints, - float x, float y, Crit3DInterpolationSettings& mySettings) + float x, float y, float z, Crit3DInterpolationSettings& mySettings) { // search more stations to assure min points with all valid proxies float ratioMinPoints = float(1.3); @@ -1040,6 +1040,7 @@ void localSelection(vector &inputPoints, vector < unsigned int nrPrimaries = 0; float maxDistance = 0; + float maxHeightDelta = 0; while (nrValid < minPoints || (mySettings.getUseLapseRateCode() && nrPrimaries < minPoints)) { maxDistance = 0; @@ -1054,16 +1055,22 @@ void localSelection(vector &inputPoints, vector < if (checkLapseRateCode(inputPoints[i].lapseRateCode, mySettings.getUseLapseRateCode(), true)) nrPrimaries++; + + if (abs(inputPoints[i].point->z - z) > maxHeightDelta) + maxHeightDelta = abs(inputPoints[i].point->z - z); } } r0 = r1; r1 += stepRadius; } - if (maxDistance != 0) + if (maxDistance != 0 && maxHeightDelta != 0) for (i=0; i< selectedPoints.size(); i++) - selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (maxDistance*maxDistance*maxDistance),EPSILON); - + { + selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (maxDistance*maxDistance),EPSILON); + selectedPoints[i].heightWeight = 1/((2/maxHeightDelta)*selectedPoints[i].point->z+1); + //selectedPoints[i].heightWeight = 1; + } mySettings.setLocalRadius(maxDistance); } @@ -1357,50 +1364,22 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati if (mySettings->getChosenElevationFunction() == piecewiseTwo) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); - if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 0.001, -0.006, 1800, max+2, 0.01, 0.0015}; - else - { - tempParam = mySettings->getProxy(i)->getFittingParametersRange(); - tempParam[1] = min-2; - tempParam[5] = max+2; - } + tempParam = {-200, min-2, 0, -0.015, 2000, max+2, 0.01, 0.0015}; } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); - if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 100, 0.001, -0.006, -0.006, 1800, max+2, 1000, 0.007, 0.0015, 0.0015}; - else - { - tempParam = mySettings->getProxy(i)->getFittingParametersRange(); - tempParam[1] = min-2; - tempParam[7] = max+2; - } + tempParam = {-200, min-2, 100, 0, -0.015, -0.015, 2000, max+2, 1000, 0.007, 0.0015, 0.0015}; } else if (mySettings->getChosenElevationFunction() == piecewiseThree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {-200, min-2, 100, 0.001, -0.006, 1800, max+2, 1000, 0.007, 0.0015}; - else - { - tempParam = mySettings->getProxy(i)->getFittingParametersRange(); - tempParam[1] = min-2; - tempParam[6] = max+2; - } + tempParam = {-200, min-2, 100, 0, -0.015, 2000, max+2, 1000, 0.007, 0.0015}; } else if (mySettings->getChosenElevationFunction() == freiFree) { mySettings->getProxy(i)->setFittingFunctionName(freiFree); - if ((mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 1800, 1000, 0.006}; - else - { - tempParam = mySettings->getProxy(i)->getFittingParametersRange(); - tempParam[0] = min-2; - tempParam[6] = max+10; - } + tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 2000, 1000, 0.006}; } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } @@ -1441,7 +1420,11 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 isPreviousParam = true; } } - else return false; + else + { + errorStr = "no proxy selected."; + return false; + } const double RATIO_DELTA = 1000; @@ -1653,14 +1636,14 @@ bool multipleDetrendingMain(std::vector &myPoints elevationCombination.setProxyActive(elevationPos, true); if (!multipleDetrendingElevation(elevationCombination, elevationParameters, myPoints, mySettings, myVar, errorStr)) - return true; + return false; } Crit3DProxyCombination othersCombination = mySettings->getSelectedCombination(); othersCombination.setProxyActive(elevationPos,false); if (!multipleDetrending(othersCombination, otherParameters, myPoints, mySettings, myVar, errorStr)) - return true; + return false; return true; @@ -1784,7 +1767,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st { predictors.push_back(myPoints[i].getProxyValue(elevationPos)); predictands.push_back(myPoints[i].value); - weights.push_back(myPoints[i].regressionWeight); + weights.push_back(myPoints[i].regressionWeight*myPoints[i].heightWeight); } } @@ -1811,6 +1794,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st if (! setAllFittingParameters_noRange(elevationCombination, mySettings, myFunc, parametersMin, parametersMax, parametersDelta, parameters, errorStr)) { + errorStr = "couldn't prepare the fitting parameters for proxy: elevation."; return false; } int pos = 0; @@ -1819,7 +1803,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st if (!func) { - errorStr = "Wrong or missing fitting function for proxy: elevation."; + errorStr = "wrong or missing fitting function for proxy: elevation."; return false; } @@ -2038,9 +2022,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector &inputPoints, std::vector &selectedPoints, - float x, float y, Crit3DInterpolationSettings &mySettings); + float x, float y, float z, Crit3DInterpolationSettings &mySettings); bool proxyValidity(std::vector &myPoints, int proxyPos, float stdDevThreshold, double &avg, double &stdDev); diff --git a/interpolation/interpolationPoint.h b/interpolation/interpolationPoint.h index 82caaef5..126df5b9 100644 --- a/interpolation/interpolationPoint.h +++ b/interpolation/interpolationPoint.h @@ -22,6 +22,7 @@ float distance; float value; float regressionWeight; + float heightWeight; lapseRateCodeType lapseRateCode; gis::Crit3DRasterGrid* topographicDistance; std::vector proxyValues; diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index e54a1b74..202b49b7 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -2002,7 +2002,7 @@ namespace interpolation const int numSteps = 40; int directions[] = {1, -1}; - int numParamsToVary = parameters.size(); + size_t numParamsToVary = parameters.size(); std::vector firstGuessParam = parameters; for (int step = 1; step <= numSteps; ++step) diff --git a/project/project.cpp b/project/project.cpp index c818c219..65947fc6 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2389,7 +2389,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT getProxyValuesXY(x, y, &interpolationSettings, proxyValues); std::vector subsetInterpolationPoints; - localSelection(interpolationPoints, subsetInterpolationPoints, x, y, interpolationSettings); + localSelection(interpolationPoints, subsetInterpolationPoints, x, y,outputPoints[i].z, interpolationSettings); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, meteoPoints, nrMeteoPoints, myVar, myTime, errorStdStr)) { @@ -2433,7 +2433,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT if (! getProxyValuesXY(x, y, &interpolationSettings, proxyValues)) interpolationSettings.setProxiesComplete(false); std::vector subsetInterpolationPoints; - localSelection(interpolationPoints, subsetInterpolationPoints, x, y, interpolationSettings); + localSelection(interpolationPoints, subsetInterpolationPoints, x, y, z, interpolationSettings); if (interpolationSettings.getUseLocalDetrending()) interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col, myCombination.getActiveProxySize())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, @@ -2736,7 +2736,7 @@ bool Project::interpolationGrid(meteoVariable myVar, const Crit3DTime& myTime) if (interpolationSettings.getUseLocalDetrending()) { std::vector subsetInterpolationPoints; - localSelection(interpolationPoints, subsetInterpolationPoints, myX, myY, interpolationSettings); + localSelection(interpolationPoints, subsetInterpolationPoints, myX, myY, myZ, interpolationSettings); interpolationSettings.setFittingParameters(meteoGridDbHandler->meteoGrid()->dataMeteoGrid.prepareParameters(row, col, myCombination.getActiveProxySize())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, meteoPoints, nrMeteoPoints, myVar, myTime, errorStdStr)) diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 2c2701b9..50a67dd4 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -379,7 +379,7 @@ void Crit3DLocalProxyWidget::plot() interpolationSettings, meteoSettings, climateParam, outInterpolationPoints, checkSpatialQuality, errorStdStr); - localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, *interpolationSettings); + localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); detrending(subsetInterpolationPoints, interpolationSettings->getSelectedCombination(), interpolationSettings, climateParam, myVar, getCurrentTime()); } else @@ -387,7 +387,7 @@ void Crit3DLocalProxyWidget::plot() checkAndPassDataToInterpolation(quality, myVar, meteoPoints, nrMeteoPoints, getCurrentTime(), SQinterpolationSettings, interpolationSettings, meteoSettings, climateParam, outInterpolationPoints, checkSpatialQuality, errorStdStr); - localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, *interpolationSettings); + localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); } QList pointListPrimary, pointListSecondary, pointListSupplemental, pointListMarked; QMap< QString, QPointF > idPointMap1; diff --git a/proxyWidget/localProxyWidget.h b/proxyWidget/localProxyWidget.h index a367eae6..cb62df4f 100644 --- a/proxyWidget/localProxyWidget.h +++ b/proxyWidget/localProxyWidget.h @@ -27,6 +27,7 @@ class Crit3DLocalProxyWidget : public QWidget private: double x; double y; + double z; std::vector> parameters; gis::Crit3DGisSettings gisSettings; Crit3DInterpolationSettings* interpolationSettings; From 8664df25344766319ead962e33a97cf3df98bef2 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 20 Jun 2024 18:55:51 +0200 Subject: [PATCH 089/179] fix initialize models --- gis/gis.cpp | 3 ++- project/meteoMaps.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index ef6f831f..7a0a1fbd 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -622,7 +622,8 @@ namespace gis } /*! no values */ - if (isFirstValue) return false; + if (isFirstValue) + return false; myGrid->maximum = maximum; myGrid->minimum = minimum; diff --git a/project/meteoMaps.cpp b/project/meteoMaps.cpp index f790088a..e20d9863 100644 --- a/project/meteoMaps.cpp +++ b/project/meteoMaps.cpp @@ -2,6 +2,7 @@ #include "basicMath.h" #include "meteo.h" #include "meteoMaps.h" +#include "gis.h" Crit3DDailyMeteoMaps::Crit3DDailyMeteoMaps(const gis::Crit3DRasterGrid& DEM) From 30f538cf8b4a760e6a21e406795ed8e059f7b2b6 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 21 Jun 2024 13:39:43 +0200 Subject: [PATCH 090/179] update praga --- dbMeteoGrid/dbMeteoGrid.cpp | 780 ++++++++---------- dbMeteoGrid/dbMeteoGrid.h | 145 ++-- homogeneityWidget/annualSeriesChartView.cpp | 2 +- homogeneityWidget/homogeneityChartView.cpp | 2 +- interpolation/interpolation.cpp | 6 +- meteo/meteoPoint.cpp | 6 +- .../pointStatisticsWidget.cpp | 22 +- project/project.cpp | 15 +- 8 files changed, 457 insertions(+), 521 deletions(-) diff --git a/dbMeteoGrid/dbMeteoGrid.cpp b/dbMeteoGrid/dbMeteoGrid.cpp index 580322c5..09f093b0 100644 --- a/dbMeteoGrid/dbMeteoGrid.cpp +++ b/dbMeteoGrid/dbMeteoGrid.cpp @@ -37,14 +37,14 @@ bool Crit3DMeteoGridDbHandler::parseXMLFile(QString xmlFileName, QDomDocument* x return (false); } - QString myError; + QString errorStr; int myErrLine, myErrColumn; - if (!xmlDoc->setContent(&myFile, &myError, &myErrLine, &myErrColumn)) + if (!xmlDoc->setContent(&myFile, &errorStr, &myErrLine, &myErrColumn)) { *error = "Parse xml failed:" + xmlFileName + " Row: " + QString::number(myErrLine) + " - Column: " + QString::number(myErrColumn) - + "\n" + myError; + + "\n" + errorStr; myFile.close(); return(false); } @@ -54,11 +54,11 @@ bool Crit3DMeteoGridDbHandler::parseXMLFile(QString xmlFileName, QDomDocument* x } -bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myError) +bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *errorStr) { QDomDocument xmlDoc; - if (! parseXMLFile(xmlFileName, &xmlDoc, myError)) return false; + if (! parseXMLFile(xmlFileName, &xmlDoc, errorStr)) return false; QDomNode child; QDomNode secondChild; @@ -86,7 +86,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing provider"; + *errorStr = "Missing provider"; return false; } _connection.provider = child.toElement().text(); @@ -97,7 +97,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing server"; + *errorStr = "Missing server"; return false; } _connection.server = child.toElement().text(); @@ -108,7 +108,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing name"; + *errorStr = "Missing name"; return false; } _connection.name = child.toElement().text(); @@ -119,7 +119,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing user"; + *errorStr = "Missing user"; return false; } _connection.user = child.toElement().text(); @@ -130,7 +130,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing password"; + *errorStr = "Missing password"; return false; } _connection.password = child.toElement().text(); @@ -153,7 +153,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro } else { - *myError = "Invalid isRegular attribute"; + *errorStr = "Invalid isRegular attribute"; return false; } @@ -167,7 +167,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro } else { - *myError = "Invalid isutm attribute"; + *errorStr = "Invalid isutm attribute"; return false; } @@ -181,7 +181,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro } else { - *myError = "Invalid istin attribute"; + *errorStr = "Invalid istin attribute"; return false; } @@ -196,7 +196,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro } else { - *myError = "Invalid isfixedfields attribute"; + *errorStr = "Invalid isfixedfields attribute"; return false; } @@ -236,7 +236,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing XLL"; + *errorStr = "Missing XLL"; return false; } header.llCorner.longitude = child.toElement().text().toFloat(); @@ -245,7 +245,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing YLL"; + *errorStr = "Missing YLL"; return false; } header.llCorner.latitude = child.toElement().text().toFloat(); @@ -254,7 +254,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing NROWS"; + *errorStr = "Missing NROWS"; return false; } header.nrRows = child.toElement().text().toInt(); @@ -264,7 +264,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing NCOLS"; + *errorStr = "Missing NCOLS"; return false; } header.nrCols = child.toElement().text().toInt(); @@ -274,7 +274,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing XWIDTH"; + *errorStr = "Missing XWIDTH"; return false; } header.dx = child.toElement().text().toFloat(); @@ -283,7 +283,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { if (child.toElement().text().isEmpty()) { - *myError = "Missing YWIDTH"; + *errorStr = "Missing YWIDTH"; return false; } header.dy = child.toElement().text().toFloat(); @@ -291,7 +291,6 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro child = child.nextSibling(); } _gridStructure.setHeader(header); - } else if (ancestor.toElement().tagName().toUpper() == "TABLEDAILY") @@ -329,17 +328,14 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { mySecondTag = secondChild.toElement().tagName().toUpper(); - if (mySecondTag == "VARFIELD") { _tableDaily.varcode[_tableDaily.varcode.size()-1].varField = secondChild.toElement().text(); - } else if (mySecondTag == "VARCODE") { _tableDaily.varcode[_tableDaily.varcode.size()-1].varCode = secondChild.toElement().text().toInt(); - } else if (mySecondTag == "VARPRAGANAME") @@ -395,17 +391,14 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { mySecondTag = secondChild.toElement().tagName().toUpper(); - if (mySecondTag == "VARFIELD") { _tableHourly.varcode[_tableHourly.varcode.size()-1].varField = secondChild.toElement().text(); - } else if (mySecondTag == "VARCODE") { _tableHourly.varcode[_tableHourly.varcode.size()-1].varCode = secondChild.toElement().text().toInt(); - } else if (mySecondTag == "VARPRAGANAME") @@ -444,17 +437,14 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro { mySecondTag = secondChild.toElement().tagName().toUpper(); - if (mySecondTag == "VARFIELD") { _tableMonthly.varcode[_tableMonthly.varcode.size()-1].varField = secondChild.toElement().text(); - } else if (mySecondTag == "VARCODE") { _tableMonthly.varcode[_tableMonthly.varcode.size()-1].varCode = secondChild.toElement().text().toInt(); - } else if (mySecondTag == "VARPRAGANAME") @@ -479,7 +469,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro } xmlDoc.clear(); - if (!checkXML(myError)) + if (!checkXML(errorStr)) { return false; } @@ -496,9 +486,8 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro catch (const std::out_of_range& oor) { QString errMess = QString("%1 does not exist" ).arg(_tableDaily.varcode[i].varPragaName); - *myError = oor.what() + errMess; + *errorStr = oor.what() + errMess; } - } for (unsigned int i=0; i < _tableHourly.varcode.size(); i++) @@ -512,7 +501,7 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro catch (const std::out_of_range& oor) { QString errMess = QString("%1 does not exist" ).arg(_tableHourly.varcode[i].varPragaName); - *myError = oor.what() + errMess; + *errorStr = oor.what() + errMess; } } @@ -527,17 +516,17 @@ bool Crit3DMeteoGridDbHandler::parseXMLGrid(QString xmlFileName, QString *myErro catch (const std::out_of_range& oor) { QString errMess = QString("%1 does not exist" ).arg(_tableMonthly.varcode[i].varPragaName); - *myError = oor.what() + errMess; + *errorStr = oor.what() + errMess; } } _meteoGrid->setGridStructure(_gridStructure); - _meteoGrid->initMeteoPoints(nRow, nCol); return true; } + void Crit3DMeteoGridDbHandler::initMapMySqlVarType() { _mapDailyMySqlVarType[dailyAirTemperatureMin] = "float(4,1)"; @@ -570,36 +559,35 @@ void Crit3DMeteoGridDbHandler::initMapMySqlVarType() _mapHourlyMySqlVarType[windVectorDirection] = "smallint(3) UNSIGNED"; _mapHourlyMySqlVarType[referenceEvapotranspiration] = "float(3,1) UNSIGNED"; _mapHourlyMySqlVarType[leafWetness] = "tinyint(3) UNSIGNED"; - } -bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) -{ +bool Crit3DMeteoGridDbHandler::checkXML(QString *errorStr) +{ /* connection */ if (_connection.provider.isNull() || _connection.provider.isEmpty()) { - *myError = "Missing connection provider"; + *errorStr = "Missing connection provider"; return false; } if (_connection.server.isNull() || _connection.server.isEmpty()) { - *myError = "Missing connection server"; + *errorStr = "Missing connection server"; return false; } if (_connection.name.isNull() || _connection.name.isEmpty()) { - *myError = "Missing connection name"; + *errorStr = "Missing connection name"; return false; } if (_connection.user.isNull() || _connection.user.isEmpty()) { - *myError = "Missing connection user"; + *errorStr = "Missing connection user"; return false; } if (_connection.password.isNull() || _connection.password.isEmpty()) { - *myError = "Missing connection password"; + *errorStr = "Missing connection password"; return false; } @@ -607,38 +595,38 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) if (_gridStructure.header().llCorner.longitude == NODATA) { - *myError = "Error missing xll tag"; + *errorStr = "Error missing xll tag"; return false; } if (_gridStructure.header().llCorner.latitude == NODATA) { - *myError = "Error missing yll tag"; + *errorStr = "Error missing yll tag"; return false; } if (_gridStructure.header().nrRows == NODATA) { - *myError = "Error missing nrows tag"; + *errorStr = "Error missing nrows tag"; return false; } if (_gridStructure.header().nrCols == NODATA) { - *myError = "Error missing ncols tag"; + *errorStr = "Error missing ncols tag"; return false; } if (_gridStructure.header().dx == NODATA) { - *myError = "Error missing xwidth tag"; + *errorStr = "Error missing xwidth tag"; return false; } if (_gridStructure.header().dy == NODATA) { - *myError = "Error missing ywidth tag"; + *errorStr = "Error missing ywidth tag"; return false; } if (_gridStructure.isUTM() == true && _gridStructure.header().dx != _gridStructure.header().dy ) { - *myError = "UTM grid with dx != dy"; + *errorStr = "UTM grid with dx != dy"; return false; } @@ -647,13 +635,13 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) { if (_tableDaily.fieldTime.isNull() || _tableDaily.fieldTime.isEmpty()) { - *myError = "Missing table Daily fieldTime"; + *errorStr = "Missing table Daily fieldTime"; return false; } if (_tableDaily.varcode.size() < 1 && _tableHourly.varcode.size() < 1) { - *myError = "Missing daily and hourly var code"; + *errorStr = "Missing daily and hourly var code"; return false; } @@ -661,17 +649,17 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) { if (_tableDaily.varcode[i].varCode == NODATA) { - *myError = "Missing daily var code"; + *errorStr = "Missing daily var code"; return false; } if (_tableDaily.varcode[i].varPragaName.isNull() || _tableDaily.varcode[i].varPragaName.isEmpty()) { - *myError = "Missing daily varPragaName"; + *errorStr = "Missing daily varPragaName"; return false; } if (_gridStructure.isFixedFields() == true && (_tableDaily.varcode[i].varField.isNull() || _tableDaily.varcode[i].varField.isEmpty()) ) { - *myError = "Fixed Field: Missing daily varField"; + *errorStr = "Fixed Field: Missing daily varField"; return false; } } @@ -682,7 +670,7 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) { if (_tableHourly.fieldTime.isNull() || _tableHourly.fieldTime.isEmpty()) { - *myError = "Missing table Hourly fieldTime"; + *errorStr = "Missing table Hourly fieldTime"; return false; } @@ -690,17 +678,17 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) { if (_tableHourly.varcode[i].varCode == NODATA) { - *myError = "Missing daily var code"; + *errorStr = "Missing daily var code"; return false; } if (_tableHourly.varcode[i].varPragaName.isNull() || _tableHourly.varcode[i].varPragaName.isEmpty()) { - *myError = "Missing daily varPragaName"; + *errorStr = "Missing daily varPragaName"; return false; } if (_gridStructure.isFixedFields() == true && (_tableHourly.varcode[i].varField.isNull() || _tableHourly.varcode[i].varField.isEmpty()) ) { - *myError = "Fixed Field: Missing daily varField"; + *errorStr = "Fixed Field: Missing daily varField"; return false; } } @@ -713,12 +701,12 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) { if (_tableMonthly.varcode[i].varCode == NODATA) { - *myError = "Missing monthly var code"; + *errorStr = "Missing monthly var code"; return false; } if (_tableMonthly.varcode[i].varPragaName.isNull() || _tableMonthly.varcode[i].varPragaName.isEmpty()) { - *myError = "Missing monthly varPragaName"; + *errorStr = "Missing monthly varPragaName"; return false; } } @@ -727,32 +715,34 @@ bool Crit3DMeteoGridDbHandler::checkXML(QString *myError) return true; } + int Crit3DMeteoGridDbHandler::getDailyVarCode(meteoVariable meteoGridDailyVar) { - int varCode = NODATA; + //check if (meteoGridDailyVar == noMeteoVar) { return varCode; } + if (_gridDailyVar.empty()) { qDebug() << "_gridDailyVar is empty"; return varCode; } + if(_gridDailyVar.contains(meteoGridDailyVar)) { varCode = _gridDailyVar[meteoGridDailyVar]; } return varCode; - } + QString Crit3DMeteoGridDbHandler::getDailyVarField(meteoVariable meteoGridDailyVar) { - QString varField = ""; //check if (meteoGridDailyVar == noMeteoVar) @@ -769,9 +759,9 @@ QString Crit3DMeteoGridDbHandler::getDailyVarField(meteoVariable meteoGridDailyV } return varField; - } + meteoVariable Crit3DMeteoGridDbHandler::getDailyVarEnum(int varCode) { if (varCode == NODATA) @@ -794,7 +784,6 @@ meteoVariable Crit3DMeteoGridDbHandler::getDailyVarEnum(int varCode) meteoVariable Crit3DMeteoGridDbHandler::getDailyVarFieldEnum(QString varField) { - if (varField == "") { return noMeteoVar; @@ -812,53 +801,57 @@ meteoVariable Crit3DMeteoGridDbHandler::getDailyVarFieldEnum(QString varField) return noMeteoVar; } + int Crit3DMeteoGridDbHandler::getHourlyVarCode(meteoVariable meteoGridHourlyVar) { - int varCode = NODATA; + //check if (meteoGridHourlyVar == noMeteoVar) { return varCode; } + if (_gridHourlyVar.empty()) { return varCode; } + if(_gridHourlyVar.contains(meteoGridHourlyVar)) { varCode = _gridHourlyVar[meteoGridHourlyVar]; } return varCode; - } + QString Crit3DMeteoGridDbHandler::getHourlyVarField(meteoVariable meteoGridHourlyVar) { - QString varField = ""; + //check if (meteoGridHourlyVar == noMeteoVar) { return varField; } + if (_gridHourlyVarField.empty()) { return varField; } + if(_gridHourlyVarField.contains(meteoGridHourlyVar)) { varField = _gridHourlyVarField[meteoGridHourlyVar]; } return varField; - } + meteoVariable Crit3DMeteoGridDbHandler::getHourlyVarEnum(int varCode) { - if (varCode == NODATA) { return noMeteoVar; @@ -874,12 +867,11 @@ meteoVariable Crit3DMeteoGridDbHandler::getHourlyVarEnum(int varCode) } return noMeteoVar; - } + meteoVariable Crit3DMeteoGridDbHandler::getHourlyVarFieldEnum(QString varField) { - if (varField == "") { return noMeteoVar; @@ -895,9 +887,9 @@ meteoVariable Crit3DMeteoGridDbHandler::getHourlyVarFieldEnum(QString varField) } return noMeteoVar; - } + int Crit3DMeteoGridDbHandler::getMonthlyVarCode(meteoVariable meteoGridMonthlyVar) { @@ -917,9 +909,9 @@ int Crit3DMeteoGridDbHandler::getMonthlyVarCode(meteoVariable meteoGridMonthlyVa } return varCode; - } + QString Crit3DMeteoGridDbHandler::getMonthlyVarField(meteoVariable meteoGridMonthlyVar) { @@ -965,7 +957,6 @@ meteoVariable Crit3DMeteoGridDbHandler::getMonthlyVarEnum(int varCode) meteoVariable Crit3DMeteoGridDbHandler::getMonthlyVarFieldEnum(QString varField) { - if (varField == "") { return noMeteoVar; @@ -981,12 +972,11 @@ meteoVariable Crit3DMeteoGridDbHandler::getMonthlyVarFieldEnum(QString varField) } return noMeteoVar; - } + std::string Crit3DMeteoGridDbHandler::getDailyPragaName(meteoVariable meteoVar) { - std::map::const_iterator it; std::string key = ""; @@ -998,12 +988,13 @@ std::string Crit3DMeteoGridDbHandler::getDailyPragaName(meteoVariable meteoVar) break; } } + return key; } + std::string Crit3DMeteoGridDbHandler::getHourlyPragaName(meteoVariable meteoVar) { - std::map::const_iterator it; std::string key = ""; @@ -1015,12 +1006,13 @@ std::string Crit3DMeteoGridDbHandler::getHourlyPragaName(meteoVariable meteoVar) break; } } + return key; } + std::string Crit3DMeteoGridDbHandler::getMonthlyPragaName(meteoVariable meteoVar) { - std::map::const_iterator it; std::string key = ""; @@ -1032,13 +1024,13 @@ std::string Crit3DMeteoGridDbHandler::getMonthlyPragaName(meteoVariable meteoVar break; } } + return key; } -bool Crit3DMeteoGridDbHandler::openDatabase(QString *myError) +bool Crit3DMeteoGridDbHandler::openDatabase(QString *errorStr) { - if (_connection.provider.toUpper() == "MYSQL") { _db = QSqlDatabase::addDatabase("QMYSQL", "grid"); @@ -1051,16 +1043,16 @@ bool Crit3DMeteoGridDbHandler::openDatabase(QString *myError) if (!_db.open()) { - *myError = "Connection with database fail.\n" + _db.lastError().text(); + *errorStr = "Connection with database fail.\n" + _db.lastError().text(); return false; } - else - return true; + + return true; } -bool Crit3DMeteoGridDbHandler::newDatabase(QString *myError) -{ +bool Crit3DMeteoGridDbHandler::newDatabase(QString *errorStr) +{ if (_connection.provider.toUpper() == "MYSQL") { _db = QSqlDatabase::addDatabase("QMYSQL"); @@ -1077,20 +1069,22 @@ bool Crit3DMeteoGridDbHandler::newDatabase(QString *myError) if (!query.exec()) { - *myError = "MySQL error:" + query.lastError().text(); + *errorStr = "MySQL error:" + query.lastError().text(); return false; } + _db.setDatabaseName(_connection.name); if (!_db.open()) { - *myError = "Connection with database fail.\n" + _db.lastError().text(); + *errorStr = "Connection with database fail.\n" + _db.lastError().text(); return false; } - else - return true; + + return true; } -bool Crit3DMeteoGridDbHandler::deleteDatabase(QString *myError) + +bool Crit3DMeteoGridDbHandler::deleteDatabase(QString *errorStr) { QSqlQuery query(_db); @@ -1098,15 +1092,16 @@ bool Crit3DMeteoGridDbHandler::deleteDatabase(QString *myError) if (!query.exec()) { - *myError = "MySQL error:" + query.lastError().text(); + *errorStr = "MySQL error:" + query.lastError().text(); return false; } + return true; } -bool Crit3DMeteoGridDbHandler::newDatabase(QString *myError, QString connectionName) -{ +bool Crit3DMeteoGridDbHandler::newDatabase(QString *errorStr, QString connectionName) +{ if (_connection.provider.toUpper() == "MYSQL") { _db = QSqlDatabase::addDatabase("QMYSQL", connectionName); @@ -1123,22 +1118,23 @@ bool Crit3DMeteoGridDbHandler::newDatabase(QString *myError, QString connectionN if (!query.exec()) { - *myError = "MySQL error:" + query.lastError().text(); + *errorStr = "MySQL error:" + query.lastError().text(); return false; } + _db.setDatabaseName(_connection.name); if (!_db.open()) { - *myError = "Connection with database fail.\n" + _db.lastError().text(); + *errorStr = "Connection with database fail.\n" + _db.lastError().text(); return false; } - else - return true; + + return true; } -bool Crit3DMeteoGridDbHandler::openDatabase(QString *myError, QString connectionName) -{ +bool Crit3DMeteoGridDbHandler::openDatabase(QString *errorStr, QString connectionName) +{ if (_connection.provider.toUpper() == "MYSQL") { _db = QSqlDatabase::addDatabase("QMYSQL", connectionName); @@ -1151,11 +1147,11 @@ bool Crit3DMeteoGridDbHandler::openDatabase(QString *myError, QString connection if (!_db.open()) { - *myError = "Connection with database fail.\n" + _db.lastError().text(); + *errorStr = "Connection with database fail.\n" + _db.lastError().text(); return false; } - else - return true; + + return true; } @@ -1170,7 +1166,7 @@ void Crit3DMeteoGridDbHandler::closeDatabase() } } -bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) +bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *errorStr) { QSqlQuery qry(_db); int row, col, active, height; @@ -1179,7 +1175,7 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) qry.prepare( "SHOW TABLES LIKE '%ells%roperties'" ); if( !qry.exec() ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -1192,7 +1188,7 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -1203,7 +1199,7 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) if (! getValue(qry.value("Code"), &code)) { - *myError = "Missing data: Code"; + *errorStr = "Missing data: Code"; return false; } @@ -1215,13 +1211,13 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) if (! getValue(qry.value("Row"), &row)) { - *myError = "Missing data: Row"; + *errorStr = "Missing data: Row"; return false; } if (! getValue(qry.value("Col"), &col)) { - *myError = "Missing data: Col"; + *errorStr = "Missing data: Col"; return false; } @@ -1237,7 +1233,7 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) if (! getValue(qry.value("Active"), &active)) { - *myError = "Missing data: Active"; + *errorStr = "Missing data: Active"; return false; } @@ -1248,7 +1244,7 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) } else { - *myError = "Row or Col > nrRows or nrCols"; + *errorStr = "Row or Col > nrRows or nrCols"; return false; } } @@ -1257,7 +1253,7 @@ bool Crit3DMeteoGridDbHandler::loadCellProperties(QString *myError) } -bool Crit3DMeteoGridDbHandler::newCellProperties(QString *myError) +bool Crit3DMeteoGridDbHandler::newCellProperties(QString *errorStr) { QSqlQuery qry(_db); QString table = "CellsProperties"; @@ -1267,14 +1263,14 @@ bool Crit3DMeteoGridDbHandler::newCellProperties(QString *myError) if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } return true; } -bool Crit3DMeteoGridDbHandler::writeCellProperties(QString *myError, int nRow, int nCol) +bool Crit3DMeteoGridDbHandler::writeCellProperties(QString *errorStr, int nRow, int nCol) { QSqlQuery qry(_db); QString table = "CellsProperties"; @@ -1295,21 +1291,21 @@ bool Crit3DMeteoGridDbHandler::writeCellProperties(QString *myError, int nRow, i if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } return true; } -bool Crit3DMeteoGridDbHandler::activeAllCells(QString *myError) +bool Crit3DMeteoGridDbHandler::activeAllCells(QString *errorStr) { QSqlQuery qry(_db); qry.prepare( "UPDATE CellsProperties SET Active = 1" ); if( !qry.exec() ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -1318,14 +1314,14 @@ bool Crit3DMeteoGridDbHandler::activeAllCells(QString *myError) } } -bool Crit3DMeteoGridDbHandler::setActiveStateCellsInList(QString *myError, QList idList, bool activeState) +bool Crit3DMeteoGridDbHandler::setActiveStateCellsInList(QString *errorStr, QList idList, bool activeState) { QSqlQuery qry(_db); QString statement = QString("UPDATE CellsProperties SET Active = %1 WHERE `Code` IN ('%2')").arg(activeState).arg(idList.join("','")); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -1334,7 +1330,7 @@ bool Crit3DMeteoGridDbHandler::setActiveStateCellsInList(QString *myError, QList } } -bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString idMeteo) +bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *errorStr, QString idMeteo) { QSqlQuery qry(_db); int row, col, active, height; @@ -1343,7 +1339,7 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i qry.prepare( "SHOW TABLES LIKE '%ells%roperties'" ); if( !qry.exec() ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -1352,11 +1348,11 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i tableCellsProp = qry.value(0).toString(); } - QString statement = QString("SELECT * FROM `%1` WHERE `Code` = '%2'").arg(tableCellsProp).arg(idMeteo); + QString statement = QString("SELECT * FROM `%1` WHERE `Code` = '%2'").arg(tableCellsProp, idMeteo); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -1367,7 +1363,7 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i if (! getValue(qry.value("Code"), &code)) { - *myError = "Missing data: Code"; + *errorStr = "Missing data: Code"; return false; } @@ -1379,13 +1375,13 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i if (! getValue(qry.value("Row"), &row)) { - *myError = "Missing data: Row"; + *errorStr = "Missing data: Row"; return false; } if (! getValue(qry.value("Col"), &col)) { - *myError = "Missing data: Col"; + *errorStr = "Missing data: Col"; return false; } @@ -1401,7 +1397,7 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i if (! getValue(qry.value("Active"), &active)) { - *myError = "Missing data: Active"; + *errorStr = "Missing data: Active"; return false; } @@ -1412,7 +1408,7 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i } else { - *myError = "Row or Col > nrRows or nrCols"; + *errorStr = "Row or Col > nrRows or nrCols"; return false; } } @@ -1421,12 +1417,12 @@ bool Crit3DMeteoGridDbHandler::loadIdMeteoProperties(QString *myError, QString i } -bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) +bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &errorStr) { QList tableList = _db.tables(QSql::Tables); if (tableList.size() <= 1) { - myError = "No data."; + errorStr = "No data."; return false; } @@ -1437,7 +1433,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if (!_meteoGrid->findFirstActiveMeteoPoint(&id, &row, &col)) { - myError = "No active cells."; + errorStr = "No active cells."; return false; } @@ -1477,7 +1473,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if (!_meteoGrid->findFirstActiveMeteoPoint(&id, &row, &col)) { - myError = "active cell not found"; + errorStr = "active cell not found"; return false; } tableD = _tableDaily.prefix + QString::fromStdString(id) + _tableDaily.postFix; @@ -1489,7 +1485,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if ( qry.lastError().type() != QSqlError::NoError ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1509,7 +1505,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) } else { - myError = "Daily time field not found: " + _tableDaily.fieldTime; + errorStr = "Daily time field not found: " + _tableDaily.fieldTime; return false; } } @@ -1535,7 +1531,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if (! _meteoGrid->findFirstActiveMeteoPoint(&id, &row, &col)) { - myError = "active cell not found"; + errorStr = "active cell not found"; return false; } @@ -1548,7 +1544,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if ( qry.lastError().type() != QSqlError::NoError && qry.lastError().nativeErrorCode() != tableNotFoundError) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1569,7 +1565,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) } else { - myError = "Hourly time field not found: " + _tableHourly.fieldTime; + errorStr = "Hourly time field not found: " + _tableHourly.fieldTime; return false; } } @@ -1584,7 +1580,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if(! qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } @@ -1597,7 +1593,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if ( qry.lastError().type() != QSqlError::NoError ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1609,7 +1605,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) } else { - myError = "PragaYear field not found"; + errorStr = "PragaYear field not found"; return false; } } @@ -1618,7 +1614,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if ( qry.lastError().type() != QSqlError::NoError ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1629,7 +1625,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) } else { - myError = "PragaMonth field not found"; + errorStr = "PragaMonth field not found"; return false; } } @@ -1639,7 +1635,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if ( qry.lastError().type() != QSqlError::NoError ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1650,7 +1646,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) } else { - myError = "PragaMonth field not found"; + errorStr = "PragaMonth field not found"; return false; } } @@ -1695,7 +1691,7 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) if (_firstDate == noDate || _lastDate == noDate) { - myError = "Missing data."; + errorStr = "Missing data."; return false; } @@ -1703,15 +1699,15 @@ bool Crit3DMeteoGridDbHandler::updateMeteoGridDate(QString &myError) } -bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate) +bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &errorStr, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate) { - myError = ""; + errorStr = ""; QString tableD = _tableDaily.prefix + meteoPointId + _tableDaily.postFix; unsigned row, col; if (! _meteoGrid->findMeteoPointFromId(&row, &col, meteoPointId.toStdString()) ) { - myError = "Missing meteoPoint id: " + meteoPointId; + errorStr = "Missing meteoPoint id: " + meteoPointId; return false; } @@ -1724,7 +1720,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString { if (firstDate > _lastDailyDate || lastDate < _firstDailyDate) { - myError = "Missing data in this time interval."; + errorStr = "Missing data in this time interval."; return false; } } @@ -1749,7 +1745,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString if(! qry.exec()) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } @@ -1765,14 +1761,14 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString { if (! getValue(qry.value(_tableDaily.fieldTime), &date)) { - myError = "Missing " + _tableDaily.fieldTime; + errorStr = "Missing " + _tableDaily.fieldTime; return false; } } if (! getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode"; + errorStr = "Missing VariableCode"; return false; } @@ -1780,7 +1776,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString if (! _meteoGrid->meteoPointPointer(row, col)->setMeteoPointValueD(getCrit3DDate(date), variable, value)) { - myError = "Error in setMeteoPointValueD"; + errorStr = "Error in setMeteoPointValueD"; return false; } } @@ -1789,15 +1785,15 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString return true; } -bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate) +bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &errorStr, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate) { - myError = ""; + errorStr = ""; QString tableD = _tableDaily.prefix + meteoPointId + _tableDaily.postFix; unsigned row, col; if ( !_meteoGrid->findMeteoPointFromId(&row, &col, meteoPointId.toStdString()) ) { - myError = "Missing meteoPoint id: " + meteoPointId; + errorStr = "Missing meteoPoint id: " + meteoPointId; return false; } @@ -1810,7 +1806,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QS { if (firstDate > _lastDailyDate || lastDate < _firstDailyDate) { - myError = "Missing data in this time interval."; + errorStr = "Missing data in this time interval."; return false; } } @@ -1844,7 +1840,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QS if(! qry.exec()) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } @@ -1860,14 +1856,14 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QS { if (! getValue(qry.value(_tableDaily.fieldTime), &date)) { - myError = "Missing " + _tableDaily.fieldTime; + errorStr = "Missing " + _tableDaily.fieldTime; return false; } } if (! getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode"; + errorStr = "Missing VariableCode"; return false; } @@ -1875,7 +1871,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QS if (! _meteoGrid->meteoPointPointer(row, col)->setMeteoPointValueD(getCrit3DDate(date), variable, value)) { - myError = "Error in setMeteoPointValueD"; + errorStr = "Error in setMeteoPointValueD"; return false; } } @@ -1885,13 +1881,13 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QS } -bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDate first, QDate last) +bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &errorStr, QString meteoPoint, int memberNr, QDate first, QDate last) { - myError = ""; + errorStr = ""; if (!_meteoGrid->gridStructure().isEnsemble()) { - myError = "Grid structure has not ensemble field"; + errorStr = "Grid structure has not ensemble field"; return false; } @@ -1905,17 +1901,17 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &myError, QStri if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id"; + errorStr = "Missing MeteoPoint id"; return false; } int numberOfDays = first.daysTo(last) + 1; _meteoGrid->meteoPointPointer(row,col)->initializeObsDataD(numberOfDays, getCrit3DDate(first)); - QString statement = QString("SELECT * FROM `%1` WHERE `%2`>= '%3' AND `%2`<= '%4' AND MemberNr = '%5' ORDER BY `%2`").arg(tableD).arg(_tableDaily.fieldTime).arg(first.toString("yyyy-MM-dd")).arg(last.toString("yyyy-MM-dd")).arg(memberNr); + QString statement = QString("SELECT * FROM `%1` WHERE `%2`>= '%3' AND `%2`<= '%4' AND MemberNr = '%5' ORDER BY `%2`").arg(tableD, _tableDaily.fieldTime).arg(first.toString("yyyy-MM-dd")).arg(last.toString("yyyy-MM-dd")).arg(memberNr); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1924,19 +1920,19 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &myError, QStri { if (!getValue(qry.value(_tableDaily.fieldTime), &date)) { - myError = "Missing fieldTime"; + errorStr = "Missing fieldTime"; return false; } if (!getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode"; + errorStr = "Missing VariableCode"; return false; } if (!getValue(qry.value("Value"), &value)) { - myError = "Missing Value"; + errorStr = "Missing Value"; } meteoVariable variable = getDailyVarEnum(varCode); @@ -1950,9 +1946,9 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &myError, QStri } -bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &myError, QString meteoPoint, QDate first, QDate last) +bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &errorStr, QString meteoPoint, QDate first, QDate last) { - myError = ""; + errorStr = ""; QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPoint + _tableDaily.postFix; @@ -1964,7 +1960,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &myError, QS if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id"; + errorStr = "Missing MeteoPoint id"; return false; } @@ -1975,7 +1971,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &myError, QS _tableDaily.fieldTime, first.toString("yyyy-MM-dd"), last.toString("yyyy-MM-dd")); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -1984,7 +1980,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &myError, QS { if (!getValue(qry.value(_tableDaily.fieldTime), &date)) { - myError = "Missing fieldTime"; + errorStr = "Missing fieldTime"; return false; } @@ -1993,7 +1989,7 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &myError, QS varCode = _tableDaily.varcode[i].varCode; if (!getValue(qry.value(_tableDaily.varcode[i].varField), &value)) { - myError = "Missing VarField"; + errorStr = "Missing VarField"; } meteoVariable variable = getDailyVarEnum(varCode); @@ -2008,15 +2004,15 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyDataFixedFields(QString &myError, QS } -bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &myError, QString meteoPoint, QDateTime firstDate, QDateTime lastDate) +bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &errorStr, QString meteoPoint, QDateTime firstDate, QDateTime lastDate) { - myError = ""; + errorStr = ""; QString tableH = _tableHourly.prefix + meteoPoint + _tableHourly.postFix; unsigned row, col; - if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) + if (! _meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id"; + errorStr = "Missing MeteoPoint id"; return false; } @@ -2025,7 +2021,7 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &myError, QString mete if (firstDate.date() > _lastHourlyDate || lastDate.date() < _firstHourlyDate) { - myError = "missing data"; + errorStr = "missing data"; return false; } @@ -2037,9 +2033,9 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &myError, QString mete .arg(tableH, _tableHourly.fieldTime, firstDate.toString("yyyy-MM-dd hh:mm"), lastDate.toString("yyyy-MM-dd hh:mm") ); - if( !qry.exec(statement) ) + if(! qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); } else { @@ -2051,13 +2047,13 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &myError, QString mete { if (! getValue(qry.value(_tableHourly.fieldTime), &date)) { - myError = "Missing fieldTime"; + errorStr = "Missing fieldTime"; return false; } if (! getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode"; + errorStr = "Missing VariableCode"; return false; } meteoVariable variable = getHourlyVarEnum(varCode); @@ -2065,7 +2061,7 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &myError, QString mete if (! _meteoGrid->meteoPointPointer(row,col)->setMeteoPointValueH(getCrit3DDate(date.date()), date.time().hour(), date.time().minute(), variable, value)) { - myError = "Error in setMeteoPointValueH"; + errorStr = "Wrong VariableCode: " + QString::number(varCode); return false; } } @@ -2076,13 +2072,13 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyData(QString &myError, QString mete } -bool Crit3DMeteoGridDbHandler::loadGridHourlyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDateTime first, QDateTime last) +bool Crit3DMeteoGridDbHandler::loadGridHourlyDataEnsemble(QString &errorStr, QString meteoPoint, int memberNr, QDateTime first, QDateTime last) { - myError = ""; + errorStr = ""; if (!_meteoGrid->gridStructure().isEnsemble()) { - myError = "Grid structure has not ensemble field"; + errorStr = "Grid structure has not ensemble field"; return false; } @@ -2097,7 +2093,7 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataEnsemble(QString &myError, QStr if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id"; + errorStr = "Missing MeteoPoint id"; return false; } @@ -2105,11 +2101,11 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataEnsemble(QString &myError, QStr _meteoGrid->meteoPointPointer(row, col)->initializeObsDataH(1, numberOfDays, getCrit3DDate(first.date())); QString statement = QString("SELECT * FROM `%1` WHERE `%2` >= '%3' AND `%2` <= '%4' AND MemberNr = '%5' ORDER BY `%2`") - .arg(tableH).arg(_tableHourly.fieldTime).arg(first.toString("yyyy-MM-dd hh:mm")).arg(last.toString("yyyy-MM-dd hh:mm")).arg(memberNr); + .arg(tableH, _tableHourly.fieldTime).arg(first.toString("yyyy-MM-dd hh:mm")).arg(last.toString("yyyy-MM-dd hh:mm")).arg(memberNr); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); } else { @@ -2117,19 +2113,19 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataEnsemble(QString &myError, QStr { if (!getValue(qry.value(_tableHourly.fieldTime), &date)) { - myError = "Missing fieldTime"; + errorStr = "Missing fieldTime"; return false; } if (!getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode"; + errorStr = "Missing VariableCode"; return false; } if (!getValue(qry.value("Value"), &value)) { - myError = "Missing Value"; + errorStr = "Missing Value"; } meteoVariable variable = getHourlyVarEnum(varCode); @@ -2143,9 +2139,9 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataEnsemble(QString &myError, QStr } -bool Crit3DMeteoGridDbHandler::loadGridHourlyDataFixedFields(QString &myError, QString meteoPoint, QDateTime first, QDateTime last) +bool Crit3DMeteoGridDbHandler::loadGridHourlyDataFixedFields(QString &errorStr, QString meteoPoint, QDateTime first, QDateTime last) { - myError = ""; + errorStr = ""; QSqlQuery qry(_db); QString tableH = _tableHourly.prefix + meteoPoint + _tableHourly.postFix; @@ -2158,17 +2154,17 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataFixedFields(QString &myError, Q if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id"; + errorStr = "Missing MeteoPoint id"; return false; } int numberOfDays = first.date().daysTo(last.date()); _meteoGrid->meteoPointPointer(row, col)->initializeObsDataH(1, numberOfDays, getCrit3DDate(first.date())); - QString statement = QString("SELECT * FROM `%1` WHERE `%2` >= '%3' AND `%2`<= '%4' ORDER BY `%2`").arg(tableH).arg(_tableHourly.fieldTime).arg(first.toString("yyyy-MM-dd hh:mm")).arg(last.toString("yyyy-MM-dd hh:mm")); + QString statement = QString("SELECT * FROM `%1` WHERE `%2` >= '%3' AND `%2`<= '%4' ORDER BY `%2`").arg(tableH, _tableHourly.fieldTime).arg(first.toString("yyyy-MM-dd hh:mm")).arg(last.toString("yyyy-MM-dd hh:mm")); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); } else { @@ -2176,7 +2172,7 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataFixedFields(QString &myError, Q { if (!getValue(qry.value(_tableHourly.fieldTime), &date)) { - myError = "Missing fieldTime"; + errorStr = "Missing fieldTime"; return false; } @@ -2186,7 +2182,7 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataFixedFields(QString &myError, Q if (!getValue(qry.value(_tableHourly.varcode[i].varField), &value)) { - myError = "Missing fieldTime"; + errorStr = "Missing fieldTime"; } meteoVariable variable = getHourlyVarEnum(varCode); @@ -2202,14 +2198,14 @@ bool Crit3DMeteoGridDbHandler::loadGridHourlyDataFixedFields(QString &myError, Q } -bool Crit3DMeteoGridDbHandler::loadGridMonthlySingleDate(QString &myError, const QString &meteoPoint, const QDate &myDate) +bool Crit3DMeteoGridDbHandler::loadGridMonthlySingleDate(QString &errorStr, const QString &meteoPoint, const QDate &myDate) { - myError = ""; + errorStr = ""; unsigned row, col; if (! _meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id: " + meteoPoint; + errorStr = "Missing MeteoPoint id: " + meteoPoint; return false; } @@ -2227,7 +2223,7 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlySingleDate(QString &myError, const .arg(meteoPoint).arg(year).arg(month); if(! qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } @@ -2237,7 +2233,7 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlySingleDate(QString &myError, const { if (! getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode."; + errorStr = "Missing VariableCode."; return false; } meteoVariable variable = getMonthlyVarEnum(varCode); @@ -2252,9 +2248,9 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlySingleDate(QString &myError, const } -bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &myError, QString meteoPoint, QDate firstDate, QDate lastDate) +bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &errorStr, QString meteoPoint, QDate firstDate, QDate lastDate) { - myError = ""; + errorStr = ""; QString table = "MonthlyData"; // set day to 1 to better comparison @@ -2264,7 +2260,7 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &myError, QString met unsigned row, col; if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - myError = "Missing MeteoPoint id"; + errorStr = "Missing MeteoPoint id"; return false; } @@ -2283,7 +2279,7 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &myError, QString met QString statement = QString("SELECT * FROM `%1` WHERE `PragaYear` BETWEEN %2 AND %3 AND PointCode = '%4' ORDER BY `PragaYear`").arg(table).arg(firstDate.year()).arg(lastDate.year()).arg(meteoPoint); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -2292,13 +2288,13 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &myError, QString met { if (!getValue(qry.value("PragaYear"), &year)) { - myError = "Missing PragaYear"; + errorStr = "Missing PragaYear"; return false; } if (!getValue(qry.value("PragaMonth"), &month)) { - myError = "Missing PragaMonth"; + errorStr = "Missing PragaMonth"; return false; } @@ -2310,13 +2306,13 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &myError, QString met if (!getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode"; + errorStr = "Missing VariableCode"; return false; } if (!getValue(qry.value("Value"), &value)) { - myError = "Missing Value"; + errorStr = "Missing Value"; } meteoVariable variable = getMonthlyVarEnum(varCode); @@ -2330,9 +2326,9 @@ bool Crit3DMeteoGridDbHandler::loadGridMonthlyData(QString &myError, QString met } -bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate firstDate, QDate lastDate) +bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &errorStr, QDate firstDate, QDate lastDate) { - myError = ""; + errorStr = ""; QString table = "MonthlyData"; // set day to 1 to better comparison @@ -2366,7 +2362,7 @@ bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate fi QString statement = QString("SELECT * FROM `%1` WHERE `PragaYear` BETWEEN %2 AND %3 ORDER BY `PointCode`").arg(table).arg(firstDate.year()).arg(lastDate.year()); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } else @@ -2375,13 +2371,13 @@ bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate fi { if (! getValue(qry.value("PragaYear"), &year)) { - myError = "Missing PragaYear"; + errorStr = "Missing PragaYear"; return false; } if (! getValue(qry.value("PragaMonth"), &month)) { - myError = "Missing PragaMonth"; + errorStr = "Missing PragaMonth"; return false; } @@ -2393,7 +2389,7 @@ bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate fi if (! getValue(qry.value("PointCode"), &pointCode)) { - myError = "Missing PointCode"; + errorStr = "Missing PointCode"; return false; } @@ -2408,7 +2404,7 @@ bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate fi if (! getValue(qry.value("VariableCode"), &varCode)) { - myError = "Missing VariableCode: " + QString::number(varCode); + errorStr = "Missing VariableCode: " + QString::number(varCode); return false; } @@ -2420,12 +2416,12 @@ bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate fi if (! getValue(qry.value("Value"), &value)) { - myError = "Missing Value"; + errorStr = "Missing Value"; } if (! _meteoGrid->meteoPointPointer(row, col)->setMeteoPointValueM(getCrit3DDate(monthDate), variable, value)) { - myError = "Error in setMeteoPointValueM()"; + errorStr = "Error in setMeteoPointValueM()"; return false; } } @@ -2435,7 +2431,7 @@ bool Crit3DMeteoGridDbHandler::loadGridAllMonthlyData(QString &myError, QDate fi } -std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, QString meteoPoint, +std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *errorStr, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate* firstDateDB) { @@ -2447,14 +2443,14 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, int varCode = getDailyVarCode(variable); if (varCode == NODATA) { - *myError = "Variable not existing"; + *errorStr = "Variable not existing"; return dailyVarList; } unsigned row, col; if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - *myError = "Missing MeteoPoint id"; + *errorStr = "Missing MeteoPoint id"; return dailyVarList; } @@ -2462,10 +2458,10 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, if(! qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); if (!_db.isOpen()) { - qDebug() << "qry exec: db is not open: " << *myError; + qDebug() << "qry exec: db is not open: " << *errorStr; exit(EXIT_FAILURE); } else @@ -2477,10 +2473,10 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, // read first date if (!qry.first()) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); if (!_db.isOpen()) { - qDebug() << "qry.first: db is not open: " << *myError; + qDebug() << "qry.first: db is not open: " << *errorStr; exit(EXIT_FAILURE); } else @@ -2491,10 +2487,10 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, if (!getValue(qry.value(_tableDaily.fieldTime), firstDateDB)) { - *myError = "Missing first date"; + *errorStr = "Missing first date"; if (!_db.isOpen()) { - qDebug() << "qry.value: db is not open: " << *myError; + qDebug() << "qry.value: db is not open: " << *errorStr; exit(EXIT_FAILURE); } else @@ -2507,7 +2503,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, qry.last(); if (!getValue(qry.value(_tableDaily.fieldTime), &lastDateDB)) { - *myError = "Missing last date"; + *errorStr = "Missing last date"; return dailyVarList; } @@ -2536,7 +2532,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *myError, } -std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, frequencyType freq, meteoVariable variable, QString id, QDateTime myFirstTime, QDateTime myLastTime, std::vector &dateStr) +std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *errorStr, frequencyType freq, meteoVariable variable, QString id, QDateTime myFirstTime, QDateTime myLastTime, std::vector &dateStr) { QString myDateStr; float value; @@ -2554,7 +2550,7 @@ std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, idVar = getDailyVarCode(variable); if (idVar == NODATA) { - *myError = "Variable not existing"; + *errorStr = "Variable not existing"; return allDataVarList; } tableName = _tableDaily.prefix + id + _tableDaily.postFix; @@ -2568,25 +2564,25 @@ std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, idVar = getHourlyVarCode(variable); if (idVar == NODATA) { - *myError = "Variable not existing"; + *errorStr = "Variable not existing"; return allDataVarList; } tableName = _tableHourly.prefix + id + _tableHourly.postFix; startDate = myFirstTime.date().toString("yyyy-MM-dd") + " " + myFirstTime.time().toString("hh:mm"); endDate = myLastTime.date().toString("yyyy-MM-dd") + " " + myLastTime.time().toString("hh:mm"); statement = QString( "SELECT * FROM `%1` WHERE VariableCode = '%2' AND `%3` >= '%4' AND `%3`<= '%5'") - .arg(tableName).arg(idVar).arg(_tableHourly.fieldTime).arg(startDate).arg(endDate); + .arg(tableName).arg(idVar).arg(_tableHourly.fieldTime, startDate, endDate); } else { - *myError = "Frequency should be daily or hourly"; + *errorStr = "Frequency should be daily or hourly"; return allDataVarList; } QDateTime dateTime; QDate date; if( !myQuery.exec(statement) ) { - *myError = myQuery.lastError().text(); + *errorStr = myQuery.lastError().text(); return allDataVarList; } else @@ -2597,7 +2593,7 @@ std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, { if (! getValue(myQuery.value(_tableDaily.fieldTime), &date)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return allDataVarList; } myDateStr = date.toString("yyyy-MM-dd"); @@ -2606,7 +2602,7 @@ std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, { if (! getValue(myQuery.value(_tableHourly.fieldTime), &dateTime)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return allDataVarList; } // LC dateTime.toString direttamente ritorna una stringa vuota nelle ore di passaggio all'ora legale @@ -2623,7 +2619,7 @@ std::vector Crit3DMeteoGridDbHandler::exportAllDataVar(QString *myError, } -std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString *myError, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate* firstDateDB) +std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString *errorStr, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate* firstDateDB) { QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPoint + _tableDaily.postFix; @@ -2639,7 +2635,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString if (varCode == NODATA) { - *myError = "Variable not existing"; + *errorStr = "Variable not existing"; return dailyVarList; } @@ -2655,7 +2651,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString QString statement = QString("SELECT `%1`, `%2` FROM `%3` WHERE `%1` >= '%4' AND `%1` <= '%5' ORDER BY `%1`").arg(_tableDaily.fieldTime).arg(varField).arg(tableD).arg(first.toString("yyyy-MM-dd")).arg(last.toString("yyyy-MM-dd")); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); } else { @@ -2666,13 +2662,13 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString { if (!getValue(qry.value(_tableDaily.fieldTime), firstDateDB)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return dailyVarList; } if (!getValue(qry.value(varField), &value)) { - *myError = "Missing Value"; + *errorStr = "Missing Value"; } dailyVarList.push_back(value); previousDate = *firstDateDB; @@ -2682,7 +2678,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString { if (!getValue(qry.value(_tableDaily.fieldTime), &date)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return dailyVarList; } @@ -2694,7 +2690,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString if (!getValue(qry.value(varField), &value)) { - *myError = "Missing Value"; + *errorStr = "Missing Value"; } dailyVarList.push_back(value); previousDate = date; @@ -2708,7 +2704,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVarFixedFields(QString } -std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *myError, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB) +std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *errorStr, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB) { QSqlQuery qry(_db); @@ -2728,20 +2724,20 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *myError, if (varCode == NODATA) { - *myError = "Variable not existing"; + *errorStr = "Variable not existing"; return hourlyVarList; } if (!_meteoGrid->findMeteoPointFromId(&row, &col, meteoPoint.toStdString()) ) { - *myError = "Missing MeteoPoint id"; + *errorStr = "Missing MeteoPoint id"; return hourlyVarList; } QString statement = QString("SELECT * FROM `%1` WHERE VariableCode = '%2' AND `%3` >= '%4' AND `%3` <= '%5' ORDER BY `%3`").arg(tableH).arg(varCode).arg(_tableHourly.fieldTime).arg(first.toString("yyyy-MM-dd hh:mm")).arg(last.toString("yyyy-MM-dd hh:mm")); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); } else { @@ -2752,13 +2748,13 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *myError, { if (!getValue(qry.value(_tableHourly.fieldTime), firstDateDB)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return hourlyVarList; } if (!getValue(qry.value("Value"), &value)) { - *myError = "Missing Value"; + *errorStr = "Missing Value"; } hourlyVarList.push_back(value); previousDateTime = *firstDateDB; @@ -2768,7 +2764,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *myError, { if (!getValue(qry.value(_tableHourly.fieldTime), &dateTime)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return hourlyVarList; } @@ -2780,7 +2776,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *myError, if (!getValue(qry.value("Value"), &value)) { - *myError = "Missing Value"; + *errorStr = "Missing Value"; } hourlyVarList.push_back(value); previousDateTime = dateTime; @@ -2795,7 +2791,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVar(QString *myError, } -std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QString *myError, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB) +std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QString *errorStr, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB) { QSqlQuery qry(_db); QString tableH = _tableHourly.prefix + meteoPoint + _tableHourly.postFix; @@ -2811,7 +2807,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QStrin if (varCode == NODATA) { - *myError = "Variable not existing"; + *errorStr = "Variable not existing"; return hourlyVarList; } @@ -2829,7 +2825,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QStrin QString statement = QString("SELECT `%1`, `%2` FROM `%3` WHERE `%1` >= '%4' AND `%1` <= '%5' ORDER BY `%1`").arg(_tableHourly.fieldTime).arg(varField).arg(tableH).arg(first.toString("yyyy-MM-dd hh:mm")).arg(last.toString("yyyy-MM-dd hh:mm")); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); } else { @@ -2840,13 +2836,13 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QStrin { if (!getValue(qry.value(_tableHourly.fieldTime), firstDateDB)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return hourlyVarList; } if (!getValue(qry.value(varField), &value)) { - *myError = "Missing Value"; + *errorStr = "Missing Value"; } hourlyVarList.push_back(value); previousDateTime = *firstDateDB; @@ -2856,7 +2852,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QStrin { if (!getValue(qry.value(_tableHourly.fieldTime), &dateTime)) { - *myError = "Missing fieldTime"; + *errorStr = "Missing fieldTime"; return hourlyVarList; } @@ -2868,7 +2864,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QStrin if (!getValue(qry.value(varField), &value)) { - *myError = "Missing Value"; + *errorStr = "Missing Value"; } hourlyVarList.push_back(value); previousDateTime = dateTime; @@ -2883,18 +2879,18 @@ std::vector Crit3DMeteoGridDbHandler::loadGridHourlyVarFixedFields(QStrin } -bool Crit3DMeteoGridDbHandler::saveCellGridDailyData(QString *myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, +bool Crit3DMeteoGridDbHandler::saveCellGridDailyData(QString *errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings) { QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPointID + _tableDaily.postFix; QString statement = QString("CREATE TABLE IF NOT EXISTS `%1`" - "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableD).arg(_tableDaily.fieldTime); + "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableD, _tableDaily.fieldTime); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -2919,7 +2915,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridDailyData(QString *myError, QString m if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -2929,7 +2925,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridDailyData(QString *myError, QString m // warning: delete all previous data -bool Crit3DMeteoGridDbHandler::deleteAndWriteCellGridDailyData(QString& myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, +bool Crit3DMeteoGridDbHandler::deleteAndWriteCellGridDailyData(QString& errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings) { QSqlQuery qry(_db); @@ -2938,10 +2934,10 @@ bool Crit3DMeteoGridDbHandler::deleteAndWriteCellGridDailyData(QString& myError, QString statement = QString("DROP TABLE `%1`").arg(tableD); qry.exec(statement); - statement = QString("CREATE TABLE `%1`(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableD).arg(_tableDaily.fieldTime); + statement = QString("CREATE TABLE `%1`(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableD, _tableDaily.fieldTime); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } @@ -2966,7 +2962,7 @@ bool Crit3DMeteoGridDbHandler::deleteAndWriteCellGridDailyData(QString& myError, statement = statement.left(statement.length() - 1); if( !qry.exec(statement) ) { - myError = qry.lastError().text(); + errorStr = qry.lastError().text(); return false; } @@ -2974,23 +2970,23 @@ bool Crit3DMeteoGridDbHandler::deleteAndWriteCellGridDailyData(QString& myError, } -bool Crit3DMeteoGridDbHandler::saveCellGridDailyDataEnsemble(QString *myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, +bool Crit3DMeteoGridDbHandler::saveCellGridDailyDataEnsemble(QString *errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, int memberNr, Crit3DMeteoSettings* meteoSettings) { QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPointID + _tableDaily.postFix; QString statement = QString("CREATE TABLE IF NOT EXISTS `%1`" - "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), MemberNr int(11), PRIMARY KEY(%2,VariableCode,MemberNr))").arg(tableD).arg(_tableDaily.fieldTime); + "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), MemberNr int(11), PRIMARY KEY(%2,VariableCode,MemberNr))").arg(tableD, _tableDaily.fieldTime); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else { - statement = QString(("REPLACE INTO `%1` (%2, VariableCode, Value, MemberNr) VALUES ")).arg(tableD).arg(_tableDaily.fieldTime); + statement = QString(("REPLACE INTO `%1` (%2, VariableCode, Value, MemberNr) VALUES ")).arg(tableD, _tableDaily.fieldTime); foreach (meteoVariable meteoVar, meteoVariableList) if (getVarFrequency(meteoVar) == daily) @@ -3011,7 +3007,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridDailyDataEnsemble(QString *myError, Q if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -3019,29 +3015,29 @@ bool Crit3DMeteoGridDbHandler::saveCellGridDailyDataEnsemble(QString *myError, Q return true; } -bool Crit3DMeteoGridDbHandler::saveListHourlyData(QString *myError, QString meteoPointID, QDateTime firstDateTime, meteoVariable meteoVar, QList values) +bool Crit3DMeteoGridDbHandler::saveListHourlyData(QString *errorStr, QString meteoPointID, QDateTime firstDateTime, meteoVariable meteoVar, QList values) { QSqlQuery qry(_db); QString tableH = _tableHourly.prefix + meteoPointID + _tableHourly.postFix; int varCode = getHourlyVarCode(meteoVar); QString statement = QString("CREATE TABLE IF NOT EXISTS `%1`" - "(%2 datetime, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableH).arg(_tableHourly.fieldTime); + "(%2 datetime, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableH, _tableHourly.fieldTime); qry.exec(statement); int nHours = values.size(); QDateTime last = firstDateTime.addSecs(3600*(nHours-1)); statement = QString("DELETE FROM `%1` WHERE %2 BETWEEN CAST('%3' AS DATETIME) AND CAST('%4' AS DATETIME) AND VariableCode = '%5'") - .arg(tableH).arg(_tableHourly.fieldTime).arg(firstDateTime.toString("yyyy-MM-dd hh:mm:00")).arg(last.toString("yyyy-MM-dd hh:mm:00")).arg(varCode); + .arg(tableH, _tableHourly.fieldTime).arg(firstDateTime.toString("yyyy-MM-dd hh:mm:00")).arg(last.toString("yyyy-MM-dd hh:mm:00")).arg(varCode); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else { - statement = QString(("INSERT INTO `%1` (%2, VariableCode, Value) VALUES ")).arg(tableH).arg(_tableHourly.fieldTime); + statement = QString(("INSERT INTO `%1` (%2, VariableCode, Value) VALUES ")).arg(tableH, _tableHourly.fieldTime); for (int i = 0; i values, bool reverseOrder) +bool Crit3DMeteoGridDbHandler::saveListDailyData(QString *errorStr, QString meteoPointID, QDate firstDate, meteoVariable meteoVar, QList values, bool reverseOrder) { QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPointID + _tableDaily.postFix; int varCode = getDailyVarCode(meteoVar); QString statement = QString("CREATE TABLE IF NOT EXISTS `%1`" - "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableD).arg(_tableDaily.fieldTime); + "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(%2,VariableCode))").arg(tableD, _tableDaily.fieldTime); qry.exec(statement); int nDays = values.size(); QDate lastDate = firstDate.addDays(nDays-1); statement = QString("DELETE FROM `%1` WHERE %2 BETWEEN CAST('%3' AS DATE) AND CAST('%4' AS DATE) AND VariableCode = '%5'") - .arg(tableD).arg(_tableDaily.fieldTime).arg(firstDate.toString("yyyy-MM-dd")).arg(lastDate.toString("yyyy-MM-dd")).arg(varCode); + .arg(tableD, _tableDaily.fieldTime).arg(firstDate.toString("yyyy-MM-dd")).arg(lastDate.toString("yyyy-MM-dd")).arg(varCode); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else { - statement = QString(("INSERT INTO `%1` (%2, VariableCode, Value) VALUES ")).arg(tableD).arg(_tableDaily.fieldTime); + statement = QString(("INSERT INTO `%1` (%2, VariableCode, Value) VALUES ")).arg(tableD, _tableDaily.fieldTime); for (int i = 0; i values) + +bool Crit3DMeteoGridDbHandler::saveListDailyDataEnsemble(QString *errorStr, QString meteoPointID, QDate date, meteoVariable meteoVar, QList values) { QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPointID + _tableDaily.postFix; int varCode = getDailyVarCode(meteoVar); QString statement = QString("CREATE TABLE IF NOT EXISTS `%1`" - "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), MemberNr int(11), PRIMARY KEY(%2,VariableCode,MemberNr))").arg(tableD).arg(_tableDaily.fieldTime); + "(%2 date, VariableCode tinyint(3) UNSIGNED, Value float(6,1), MemberNr int(11), PRIMARY KEY(%2,VariableCode,MemberNr))").arg(tableD, _tableDaily.fieldTime); qry.exec(statement); statement = QString("DELETE FROM `%1` WHERE %2 = DATE('%3') AND VariableCode = '%4'") - .arg(tableD).arg(_tableDaily.fieldTime).arg(date.toString("yyyy-MM-dd")).arg(varCode); - if( !qry.exec(statement) ) + .arg(tableD, _tableDaily.fieldTime, date.toString("yyyy-MM-dd")).arg(varCode); + if(! qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else { - statement = QString(("INSERT INTO `%1` (%2, VariableCode, Value, MemberNr) VALUES ")).arg(tableD).arg(_tableDaily.fieldTime); - for (int i = 0; i meteoVariableList) { QSqlQuery qry(_db); @@ -3397,7 +3397,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridMonthlyData(QString *myError, QString if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3427,7 +3427,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridMonthlyData(QString *myError, QString if( ! qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -3435,7 +3435,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridMonthlyData(QString *myError, QString return true; } -bool Crit3DMeteoGridDbHandler::saveGridData(QString *myError, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings) +bool Crit3DMeteoGridDbHandler::saveGridData(QString *errorStr, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings) { std::string id; meteoVariable var; @@ -3458,13 +3458,13 @@ bool Crit3DMeteoGridDbHandler::saveGridData(QString *myError, QDateTime firstTim { if (! gridStructure().isFixedFields()) { - if (isHourly) saveCellGridHourlyData(myError, QString::fromStdString(id), row, col, firstTime, lastTime, meteoVariableList); - if (isDaily) saveCellGridDailyData(myError, QString::fromStdString(id), row, col, firstTime.date(), lastDate, meteoVariableList, meteoSettings); + if (isHourly) saveCellGridHourlyData(errorStr, QString::fromStdString(id), row, col, firstTime, lastTime, meteoVariableList); + if (isDaily) saveCellGridDailyData(errorStr, QString::fromStdString(id), row, col, firstTime.date(), lastDate, meteoVariableList, meteoSettings); } else { - if (isHourly) saveCellGridHourlyDataFF(myError, QString::fromStdString(id), row, col, firstTime, lastTime); - if (isDaily) saveCellGridDailyDataFF(myError, QString::fromStdString(id), row, col, firstTime.date(), lastDate, meteoSettings); + if (isHourly) saveCellGridHourlyDataFF(errorStr, QString::fromStdString(id), row, col, firstTime, lastTime); + if (isDaily) saveCellGridDailyDataFF(errorStr, QString::fromStdString(id), row, col, firstTime.date(), lastDate, meteoSettings); } } @@ -3472,7 +3472,7 @@ bool Crit3DMeteoGridDbHandler::saveGridData(QString *myError, QDateTime firstTim } -bool Crit3DMeteoGridDbHandler::saveGridHourlyData(QString *myError, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList) +bool Crit3DMeteoGridDbHandler::saveGridHourlyData(QString *errorStr, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList) { std::string id; @@ -3484,11 +3484,11 @@ bool Crit3DMeteoGridDbHandler::saveGridHourlyData(QString *myError, QDateTime fi { if (!gridStructure().isFixedFields()) { - saveCellGridHourlyData(myError, QString::fromStdString(id), row, col, firstDate, lastDate, meteoVariableList); + saveCellGridHourlyData(errorStr, QString::fromStdString(id), row, col, firstDate, lastDate, meteoVariableList); } else { - saveCellGridHourlyDataFF(myError, QString::fromStdString(id), row, col, firstDate, lastDate); + saveCellGridHourlyDataFF(errorStr, QString::fromStdString(id), row, col, firstDate, lastDate); } } } @@ -3497,7 +3497,7 @@ bool Crit3DMeteoGridDbHandler::saveGridHourlyData(QString *myError, QDateTime fi return true; } -bool Crit3DMeteoGridDbHandler::saveGridDailyData(QString *myError, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings) +bool Crit3DMeteoGridDbHandler::saveGridDailyData(QString *errorStr, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings) { std::string id; @@ -3509,11 +3509,11 @@ bool Crit3DMeteoGridDbHandler::saveGridDailyData(QString *myError, QDateTime fir { if (! gridStructure().isFixedFields()) { - saveCellGridDailyData(myError, QString::fromStdString(id), row, col, firstDate.date(), lastDate.date(), meteoVariableList, meteoSettings); + saveCellGridDailyData(errorStr, QString::fromStdString(id), row, col, firstDate.date(), lastDate.date(), meteoVariableList, meteoSettings); } else { - saveCellGridDailyDataFF(myError, QString::fromStdString(id), row, col, firstDate.date(), lastDate.date(), meteoSettings); + saveCellGridDailyDataFF(errorStr, QString::fromStdString(id), row, col, firstDate.date(), lastDate.date(), meteoSettings); } } } @@ -3522,7 +3522,7 @@ bool Crit3DMeteoGridDbHandler::saveGridDailyData(QString *myError, QDateTime fir return true; } -bool Crit3DMeteoGridDbHandler::saveCellGridHourlyData(QString *myError, QString meteoPointID, int row, int col, +bool Crit3DMeteoGridDbHandler::saveCellGridHourlyData(QString *errorStr, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList) { QSqlQuery qry(_db); @@ -3530,11 +3530,11 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyData(QString *myError, QString QString statement = QString("CREATE TABLE IF NOT EXISTS `%1` " - "(`%2` datetime, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(`%2`,VariableCode))").arg(tableH).arg(_tableHourly.fieldTime); + "(`%2` datetime, VariableCode tinyint(3) UNSIGNED, Value float(6,1), PRIMARY KEY(`%2`,VariableCode))").arg(tableH, _tableHourly.fieldTime); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3559,7 +3559,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyData(QString *myError, QString if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -3567,7 +3567,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyData(QString *myError, QString return true; } -bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataEnsemble(QString *myError, QString meteoPointID, int row, int col, +bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataEnsemble(QString *errorStr, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList, int memberNr) { QSqlQuery qry(_db); @@ -3580,7 +3580,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataEnsemble(QString *myError, if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3605,7 +3605,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataEnsemble(QString *myError, if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -3613,7 +3613,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataEnsemble(QString *myError, return true; } -bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataFF(QString *myError, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime) +bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataFF(QString *errorStr, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime) { QSqlQuery qry(_db); QString tableH = _tableHourly.prefix + meteoPointID + _tableHourly.postFix; @@ -3632,7 +3632,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataFF(QString *myError, QStrin if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3660,7 +3660,7 @@ bool Crit3DMeteoGridDbHandler::saveCellGridHourlyDataFF(QString *myError, QStrin if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -3799,6 +3799,7 @@ QDate Crit3DMeteoGridDbHandler::getFirstDailyDate() const return _firstDailyDate; } + QDate Crit3DMeteoGridDbHandler::getLastDailyDate() const { if (_lastDailyDate.year() == 1800) @@ -3808,6 +3809,7 @@ QDate Crit3DMeteoGridDbHandler::getLastDailyDate() const return _lastDailyDate; } + QDate Crit3DMeteoGridDbHandler::getFirstHourlyDate() const { if (_firstHourlyDate.year() == 1800) @@ -3817,6 +3819,7 @@ QDate Crit3DMeteoGridDbHandler::getFirstHourlyDate() const return _firstHourlyDate; } + QDate Crit3DMeteoGridDbHandler::getLastHourlyDate() const { if (_lastHourlyDate.year() == 1800) @@ -3826,6 +3829,7 @@ QDate Crit3DMeteoGridDbHandler::getLastHourlyDate() const return _lastHourlyDate; } + QDate Crit3DMeteoGridDbHandler::getFirstMonthlytDate() const { if (_firstMonthlyDate.year() == 1800) @@ -3835,6 +3839,7 @@ QDate Crit3DMeteoGridDbHandler::getFirstMonthlytDate() const return _firstMonthlyDate; } + QDate Crit3DMeteoGridDbHandler::getLastMonthlyDate() const { if (_lastMonthlyDate.year() == 1800) @@ -3844,14 +3849,15 @@ QDate Crit3DMeteoGridDbHandler::getLastMonthlyDate() const return _lastMonthlyDate; } -bool Crit3DMeteoGridDbHandler::idDailyList(QString *myError, QList* idMeteoList) + +bool Crit3DMeteoGridDbHandler::idDailyList(QString *errorStr, QList* idMeteoList) { QSqlQuery qry(_db); QString statement = QString("SHOW TABLES LIKE '%1%%2'").arg(_tableDaily.prefix, _tableDaily.postFix); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3870,10 +3876,12 @@ bool Crit3DMeteoGridDbHandler::idDailyList(QString *myError, QList* idM idMeteoList->append(tableName); } } + return true; } -bool Crit3DMeteoGridDbHandler::getYearList(QString *myError, QString meteoPoint, QList* yearList) + +bool Crit3DMeteoGridDbHandler::getYearList(QString *errorStr, QString meteoPoint, QList* yearList) { QSqlQuery qry(_db); QString tableD = _tableDaily.prefix + meteoPoint + _tableDaily.postFix; @@ -3881,7 +3889,7 @@ bool Crit3DMeteoGridDbHandler::getYearList(QString *myError, QString meteoPoint, QString statement = QString("SELECT DISTINCT DATE_FORMAT(`%1`,'%Y') as Year FROM `%2` ORDER BY Year").arg(_tableDaily.fieldTime, tableD); if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3900,7 +3908,7 @@ bool Crit3DMeteoGridDbHandler::getYearList(QString *myError, QString meteoPoint, return true; } -bool Crit3DMeteoGridDbHandler::saveLogProcedures(QString *myError, QString nameProc, QDate date) +bool Crit3DMeteoGridDbHandler::saveLogProcedures(QString *errorStr, QString nameProc, QDate date) { QSqlQuery qry(_db); QString table = "log_procedures"; @@ -3910,7 +3918,7 @@ bool Crit3DMeteoGridDbHandler::saveLogProcedures(QString *myError, QString nameP if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } else @@ -3919,7 +3927,7 @@ bool Crit3DMeteoGridDbHandler::saveLogProcedures(QString *myError, QString nameP if( !qry.exec(statement) ) { - *myError = qry.lastError().text(); + *errorStr = qry.lastError().text(); return false; } } @@ -4142,83 +4150,3 @@ bool Crit3DMeteoGridDbHandler::MeteoGridToRasterFlt(double cellSize, const gis:: return true; } - -QDate Crit3DMeteoGridDbHandler::firstDate() const -{ - return _firstDate; -} - -void Crit3DMeteoGridDbHandler::setFirstDate(const QDate &firstDate) -{ - _firstDate = firstDate; -} - -QDate Crit3DMeteoGridDbHandler::lastDate() const -{ - return _lastDate; -} - -void Crit3DMeteoGridDbHandler::setLastDate(const QDate &lastDate) -{ - _lastDate = lastDate; -} - -Crit3DMeteoGrid *Crit3DMeteoGridDbHandler::meteoGrid() const -{ - return _meteoGrid; -} - -void Crit3DMeteoGridDbHandler::setMeteoGrid(Crit3DMeteoGrid *meteoGrid) -{ - _meteoGrid = meteoGrid; -} - -QSqlDatabase Crit3DMeteoGridDbHandler::db() const -{ - return _db; -} - -void Crit3DMeteoGridDbHandler::setDb(const QSqlDatabase &db) -{ - _db = db; -} - -QString Crit3DMeteoGridDbHandler::fileName() const -{ - return _fileName; -} - -TXMLConnection Crit3DMeteoGridDbHandler::connection() const -{ - return _connection; -} - -Crit3DMeteoGridStructure Crit3DMeteoGridDbHandler::gridStructure() const -{ - return _gridStructure; -} - -TXMLTable Crit3DMeteoGridDbHandler::tableDaily() const -{ - return _tableDaily; -} - -TXMLTable Crit3DMeteoGridDbHandler::tableHourly() const -{ - return _tableHourly; -} - -TXMLTable Crit3DMeteoGridDbHandler::tableMonthly() const -{ - return _tableMonthly; -} - -QString Crit3DMeteoGridDbHandler::tableDailyModel() const -{ - return _tableDailyModel; -} - -QString Crit3DMeteoGridDbHandler::tableHourlyModel() const -{ - return _tableHourlyModel; -} diff --git a/dbMeteoGrid/dbMeteoGrid.h b/dbMeteoGrid/dbMeteoGrid.h index be2f384a..4dca06f0 100644 --- a/dbMeteoGrid/dbMeteoGrid.h +++ b/dbMeteoGrid/dbMeteoGrid.h @@ -31,7 +31,6 @@ QString password; }; - struct TXMLvar { QString varField; @@ -58,35 +57,41 @@ Crit3DMeteoGridDbHandler(); ~Crit3DMeteoGridDbHandler(); - bool openDatabase(QString *myError); - bool openDatabase(QString *myError, QString connectionName); - bool newDatabase(QString *myError); - bool newDatabase(QString *myError, QString connectionName); - bool deleteDatabase(QString *myError); + QString fileName() const { return _fileName; } + TXMLConnection connection() const { return _connection; } + + QSqlDatabase db() const { return _db; } + void setDb(const QSqlDatabase &db) { _db = db; } + + QDate firstDate() const { return _firstDate; } + QDate lastDate() const { return _lastDate; } + + void setFirstDate(const QDate &firstDate) { _firstDate = firstDate; } + void setLastDate(const QDate &lastDate) { _lastDate = lastDate; } + + Crit3DMeteoGridStructure gridStructure() const { return _gridStructure; } + + Crit3DMeteoGrid *meteoGrid() const { return _meteoGrid; } + void setMeteoGrid(Crit3DMeteoGrid *meteoGrid) { _meteoGrid = meteoGrid; } + + TXMLTable tableHourly() const { return _tableHourly; } + TXMLTable tableDaily() const { return _tableDaily; } + TXMLTable tableMonthly() const { return _tableMonthly; } + + QString tableDailyModel() const { return _tableDailyModel; } + QString tableHourlyModel() const { return _tableHourlyModel; } + + bool openDatabase(QString *errorStr); + bool openDatabase(QString *errorStr, QString connectionName); + bool newDatabase(QString *errorStr); + bool newDatabase(QString *errorStr, QString connectionName); + bool deleteDatabase(QString *errorStr); void closeDatabase(); bool parseXMLFile(QString xmlFileName, QDomDocument* xmlDoc, QString *error); - bool checkXML(QString *myError); - bool parseXMLGrid(QString xmlFileName, QString *myError); + bool checkXML(QString *errorStr); + bool parseXMLGrid(QString xmlFileName, QString *errorStr); void initMapMySqlVarType(); - QSqlDatabase db() const; - QString fileName() const; - TXMLConnection connection() const; - Crit3DMeteoGridStructure gridStructure() const; - Crit3DMeteoGrid *meteoGrid() const; - QDate firstDate() const; - QDate lastDate() const; - TXMLTable tableDaily() const; - TXMLTable tableHourly() const; - TXMLTable tableMonthly() const; - QString tableDailyModel() const; - QString tableHourlyModel() const; - - void setMeteoGrid(Crit3DMeteoGrid *meteoGrid); - void setDb(const QSqlDatabase &db); - void setFirstDate(const QDate &firstDate); - void setLastDate(const QDate &lastDate); - int getDailyVarCode(meteoVariable meteoGridDailyVar); QString getDailyVarField(meteoVariable meteoGridDailyVar); meteoVariable getDailyVarEnum(int varCode); @@ -106,60 +111,60 @@ std::string getHourlyPragaName(meteoVariable meteoVar); std::string getMonthlyPragaName(meteoVariable meteoVar); - bool loadCellProperties(QString *myError); - bool newCellProperties(QString *myError); - bool writeCellProperties(QString *myError, int nRow, int nCol); - bool loadIdMeteoProperties(QString *myError, QString idMeteo); - bool updateMeteoGridDate(QString &myError); - - bool loadGridDailyData(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate); - bool loadGridDailyDataFixedFields(QString &myError, QString meteoPoint, QDate first, QDate last); - bool loadGridDailyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDate first, QDate last); - bool loadGridDailyMeteoPrec(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate); - bool loadGridHourlyData(QString &myError, QString meteoPoint, QDateTime firstDate, QDateTime lastDate); - bool loadGridHourlyDataFixedFields(QString &myError, QString meteoPoint, QDateTime first, QDateTime last); - bool loadGridHourlyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDateTime first, QDateTime last); - bool loadGridMonthlyData(QString &myError, QString meteoPoint, QDate firstDate, QDate lastDate); - bool loadGridAllMonthlyData(QString &myError, QDate firstDate, QDate lastDate); - bool loadGridMonthlySingleDate(QString &myError, const QString &meteoPoint, const QDate &myDate); - - std::vector loadGridDailyVar(QString *myError, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate *firstDateDB); - std::vector loadGridDailyVarFixedFields(QString *myError, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate* firstDateDB); - std::vector loadGridHourlyVar(QString *myError, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB); - std::vector loadGridHourlyVarFixedFields(QString *myError, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB); - std::vector exportAllDataVar(QString *myError, frequencyType freq, meteoVariable variable, QString id, QDateTime myFirstTime, QDateTime myLastTime, std::vector &dateStr); - bool getYearList(QString *myError, QString meteoPoint, QList* yearList); - bool idDailyList(QString *myError, QList* idMeteoList); - - bool saveGridData(QString *myError, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList, Crit3DMeteoSettings *meteoSettings); - bool saveGridHourlyData(QString *myError, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList); - bool saveGridDailyData(QString *myError, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList, Crit3DMeteoSettings *meteoSettings); - bool deleteAndWriteCellGridDailyData(QString& myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, + bool loadCellProperties(QString *errorStr); + bool newCellProperties(QString *errorStr); + bool writeCellProperties(QString *errorStr, int nRow, int nCol); + bool loadIdMeteoProperties(QString *errorStr, QString idMeteo); + bool updateMeteoGridDate(QString &errorStr); + + bool loadGridDailyData(QString &errorStr, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate); + bool loadGridDailyDataFixedFields(QString &errorStr, QString meteoPoint, QDate first, QDate last); + bool loadGridDailyDataEnsemble(QString &errorStr, QString meteoPoint, int memberNr, QDate first, QDate last); + bool loadGridDailyMeteoPrec(QString &errorStr, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate); + bool loadGridHourlyData(QString &errorStr, QString meteoPoint, QDateTime firstDate, QDateTime lastDate); + bool loadGridHourlyDataFixedFields(QString &errorStr, QString meteoPoint, QDateTime first, QDateTime last); + bool loadGridHourlyDataEnsemble(QString &errorStr, QString meteoPoint, int memberNr, QDateTime first, QDateTime last); + bool loadGridMonthlyData(QString &errorStr, QString meteoPoint, QDate firstDate, QDate lastDate); + bool loadGridAllMonthlyData(QString &errorStr, QDate firstDate, QDate lastDate); + bool loadGridMonthlySingleDate(QString &errorStr, const QString &meteoPoint, const QDate &myDate); + + std::vector loadGridDailyVar(QString *errorStr, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate *firstDateDB); + std::vector loadGridDailyVarFixedFields(QString *errorStr, QString meteoPoint, meteoVariable variable, QDate first, QDate last, QDate* firstDateDB); + std::vector loadGridHourlyVar(QString *errorStr, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB); + std::vector loadGridHourlyVarFixedFields(QString *errorStr, QString meteoPoint, meteoVariable variable, QDateTime first, QDateTime last, QDateTime* firstDateDB); + std::vector exportAllDataVar(QString *errorStr, frequencyType freq, meteoVariable variable, QString id, QDateTime myFirstTime, QDateTime myLastTime, std::vector &dateStr); + bool getYearList(QString *errorStr, QString meteoPoint, QList* yearList); + bool idDailyList(QString *errorStr, QList* idMeteoList); + + bool saveGridData(QString *errorStr, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList, Crit3DMeteoSettings *meteoSettings); + bool saveGridHourlyData(QString *errorStr, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList); + bool saveGridDailyData(QString *errorStr, QDateTime firstDate, QDateTime lastDate, QList meteoVariableList, Crit3DMeteoSettings *meteoSettings); + bool deleteAndWriteCellGridDailyData(QString& errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, Crit3DMeteoSettings* meteoSettings); - bool saveCellGridDailyData(QString *myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, Crit3DMeteoSettings *meteoSettings); - bool saveCellGridDailyDataFF(QString *myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, Crit3DMeteoSettings *meteoSettings); - bool saveCellGridDailyDataEnsemble(QString *myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, + bool saveCellGridDailyData(QString *errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, Crit3DMeteoSettings *meteoSettings); + bool saveCellGridDailyDataFF(QString *errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, Crit3DMeteoSettings *meteoSettings); + bool saveCellGridDailyDataEnsemble(QString *errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList, int memberNr, Crit3DMeteoSettings *meteoSettings); - bool saveCellGridMonthlyData(QString *myError, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, + bool saveCellGridMonthlyData(QString *errorStr, QString meteoPointID, int row, int col, QDate firstDate, QDate lastDate, QList meteoVariableList); - bool saveListDailyDataEnsemble(QString *myError, QString meteoPointID, QDate date, meteoVariable meteoVar, QList values); - bool saveListDailyData(QString *myError, QString meteoPointID, QDate firstDate, meteoVariable meteoVar, QList values, bool reverseOrder); - bool cleanDailyOldData(QString *myError, QDate date); - bool saveListHourlyData(QString *myError, QString meteoPointID, QDateTime firstDateTime, meteoVariable meteoVar, QList values); - bool saveCellCurrentGridDaily(QString *myError, QString meteoPointID, QDate date, int varCode, float value); + bool saveListDailyDataEnsemble(QString *errorStr, QString meteoPointID, QDate date, meteoVariable meteoVar, QList values); + bool saveListDailyData(QString *errorStr, QString meteoPointID, QDate firstDate, meteoVariable meteoVar, QList values, bool reverseOrder); + bool cleanDailyOldData(QString *errorStr, QDate date); + bool saveListHourlyData(QString *errorStr, QString meteoPointID, QDateTime firstDateTime, meteoVariable meteoVar, QList values); + bool saveCellCurrentGridDaily(QString *errorStr, QString meteoPointID, QDate date, int varCode, float value); bool saveCellCurrentGridDailyList(QString meteoPointID, QList listEntries, QString &errorStr); bool saveCellCurrentGridHourlyList(QString meteoPointID, QList listEntries, QString &errorStr); bool saveCellCurrentGridDailyFF(QString &errorStr, QString meteoPointID, QDate date, QString varPragaName, float value); - bool saveCellGridHourlyData(QString *myError, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList); - bool saveCellGridHourlyDataFF(QString *myError, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime); - bool saveCellGridHourlyDataEnsemble(QString *myError, QString meteoPointID, int row, int col, + bool saveCellGridHourlyData(QString *errorStr, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList); + bool saveCellGridHourlyDataFF(QString *errorStr, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime); + bool saveCellGridHourlyDataEnsemble(QString *errorStr, QString meteoPointID, int row, int col, QDateTime firstTime, QDateTime lastTime, QList meteoVariableList, int memberNr); bool saveCellCurrentGridHourly(QString& errorStr, QString meteoPointID, QDateTime dateTime, int varCode, float value); bool saveCellCurrentGridHourlyFF(QString &errorStr, QString meteoPointID, QDateTime dateTime, QString varPragaName, float value); - bool activeAllCells(QString *myError); - bool setActiveStateCellsInList(QString *myError, QList idList, bool activeState); + bool activeAllCells(QString *errorStr); + bool setActiveStateCellsInList(QString *errorStr, QList idList, bool activeState); bool saveDailyDataCsv(const QString &csvFileName, const QList &variableList, const QDate &firstDate, const QDate &lastDate, unsigned row, unsigned col, QString &errorStr); @@ -180,7 +185,7 @@ bool isHourly(); bool isMonthly(); - bool saveLogProcedures(QString *myError, QString nameProc, QDate date); + bool saveLogProcedures(QString *errorStr, QString nameProc, QDate date); private: diff --git a/homogeneityWidget/annualSeriesChartView.cpp b/homogeneityWidget/annualSeriesChartView.cpp index 096fb2dd..8332c69c 100644 --- a/homogeneityWidget/annualSeriesChartView.cpp +++ b/homogeneityWidget/annualSeriesChartView.cpp @@ -62,7 +62,7 @@ void AnnualSeriesChartView::draw(std::vector years, std::vector outp axisY->setMin(minValue-3); } axisX->setRange(years[0], years[years.size()-1]); - int nYears = years.size(); + int nYears = int(years.size()); if ( nYears <= 15) { axisX->setTickCount(nYears); diff --git a/homogeneityWidget/homogeneityChartView.cpp b/homogeneityWidget/homogeneityChartView.cpp index f9380be1..876ad56f 100644 --- a/homogeneityWidget/homogeneityChartView.cpp +++ b/homogeneityWidget/homogeneityChartView.cpp @@ -94,7 +94,7 @@ void HomogeneityChartView::drawSNHT(std::vector years, std::vector axisY->setMin(minValue-3); } axisX->setRange(years[0], years[years.size()-1]); - int nYears = years.size(); + int nYears = int(years.size()); if ( nYears <= 15) { axisX->setTickCount(nYears); diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index dacaf920..4e4d4a06 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1057,7 +1057,7 @@ void localSelection(vector &inputPoints, vector < nrPrimaries++; if (abs(inputPoints[i].point->z - z) > maxHeightDelta) - maxHeightDelta = abs(inputPoints[i].point->z - z); + maxHeightDelta = fabs(float(inputPoints[i].point->z) - z); } } r0 = r1; @@ -1067,8 +1067,8 @@ void localSelection(vector &inputPoints, vector < if (maxDistance != 0 && maxHeightDelta != 0) for (i=0; i< selectedPoints.size(); i++) { - selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (maxDistance*maxDistance),EPSILON); - selectedPoints[i].heightWeight = 1/((2/maxHeightDelta)*selectedPoints[i].point->z+1); + selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (maxDistance*maxDistance), EPSILON); + selectedPoints[i].heightWeight = 1./((2./maxHeightDelta)*selectedPoints[i].point->z+1); //selectedPoints[i].heightWeight = 1; } mySettings.setLocalRadius(maxDistance); diff --git a/meteo/meteoPoint.cpp b/meteo/meteoPoint.cpp index ab3908d1..4809cb3a 100644 --- a/meteo/meteoPoint.cpp +++ b/meteo/meteoPoint.cpp @@ -709,7 +709,7 @@ void Crit3DMeteoPoint::cleanObsDataM() bool Crit3DMeteoPoint::setMeteoPointValueH(const Crit3DDate& myDate, int myHour, int myMinutes, meteoVariable myVar, float myValue) { - //check + // check if (myVar == noMeteoVar || obsDataH == nullptr) { return false; @@ -718,13 +718,13 @@ bool Crit3DMeteoPoint::setMeteoPointValueH(const Crit3DDate& myDate, int myHour, // day index int i = obsDataH[0].date.daysTo(myDate); - //check if out of range (accept +1 date exceed) + // check if out of range (accept +1 date exceed) if (i < 0 || i > nrObsDataDaysH) return false; // sub hourly index int subH = int(ceil(float(myMinutes) / float(60 / hourlyFraction))); - //if +1 date exceed accept only hour 00:00 + // if +1 date exceed accept only hour 00:00 if (i == nrObsDataDaysH && (myHour != 0 || subH != 0)) return false; // hour 0 becomes hour 24 of the previous day diff --git a/pointStatisticsWidget/pointStatisticsWidget.cpp b/pointStatisticsWidget/pointStatisticsWidget.cpp index a8bf09f9..3a7fdbc5 100644 --- a/pointStatisticsWidget/pointStatisticsWidget.cpp +++ b/pointStatisticsWidget/pointStatisticsWidget.cpp @@ -697,7 +697,8 @@ void Crit3DPointStatisticsWidget::plot() double availab = double(validData) / double(count) * 100.0; availability.setText(QString::number(availab, 'f', 3)); - double mkendall = statisticalElab(mannKendall, NODATA, outputValues, outputValues.size(), meteoSettings->getRainfallThreshold()); + double mkendall = statisticalElab(mannKendall, NODATA, outputValues, int(outputValues.size()), + meteoSettings->getRainfallThreshold()); significance.setText(QString::number(mkendall, 'f', 3)); double averageValue = sum / double(validData); average.setText(QString::number(averageValue, 'f', 1)); @@ -707,7 +708,7 @@ void Crit3DPointStatisticsWidget::plot() float myR2 = NODATA; bool isZeroIntercept = false; std::vector yearsFloat(years.begin(), years.end()); - statistics::linearRegression(yearsFloat, outputValues, outputValues.size(), isZeroIntercept, + statistics::linearRegression(yearsFloat, outputValues, int(outputValues.size()), isZeroIntercept, &myIntercept, &myCoeff, &myR2); r2.setText(QString::number(double(myR2), 'f', 3)); rate.setText(QString::number(double(myCoeff), 'f', 3)); @@ -868,7 +869,8 @@ void Crit3DPointStatisticsWidget::plot() float availab = ((float)validData/(float)count)*100.0; availability.setText(QString::number(availab, 'f', 3)); - float mkendall = statisticalElab(mannKendall, NODATA, outputValues, outputValues.size(), meteoSettings->getRainfallThreshold()); + float mkendall = statisticalElab(mannKendall, NODATA, outputValues, int(outputValues.size()), + meteoSettings->getRainfallThreshold()); significance.setText(QString::number(mkendall, 'f', 3)); float averageValue = sum/validYears; average.setText(QString::number(averageValue, 'f', 1)); @@ -878,7 +880,7 @@ void Crit3DPointStatisticsWidget::plot() float myR2 = NODATA; bool isZeroIntercept = false; std::vector yearsFloat(years.begin(), years.end()); - statistics::linearRegression(yearsFloat, outputValues, outputValues.size(), isZeroIntercept, + statistics::linearRegression(yearsFloat, outputValues, int(outputValues.size()), isZeroIntercept, &myIntercept, &myCoeff, &myR2); r2.setText(QString::number(myR2, 'f', 3)); rate.setText(QString::number(myCoeff, 'f', 3)); @@ -1171,8 +1173,8 @@ void Crit3DPointStatisticsWidget::plot() } avg = statistics::mean(series, nrValues); dev_std = statistics::standardDeviation(series, nrValues); - millile3dev = sorting::percentile(sortedSeries, nrValues, 99.73, true); - millile_3Dev = sorting::percentile(sortedSeries, nrValues, 0.27, false); + millile3dev = sorting::percentile(sortedSeries, nrValues, 99.73f, true); + millile_3Dev = sorting::percentile(sortedSeries, nrValues, 0.27f, false); } availability.setText(QString::number((float)nrValues/(float)totDays * 100, 'f', 3)); @@ -1449,8 +1451,8 @@ void Crit3DPointStatisticsWidget::plot() } avg = statistics::mean(series, nrValues); dev_std = statistics::standardDeviation(series, nrValues); - millile3dev = sorting::percentile(sortedSeries, nrValues, 99.73, true); - millile_3Dev = sorting::percentile(sortedSeries, nrValues, 0.27, false); + millile3dev = sorting::percentile(sortedSeries, nrValues, 99.73f, true); + millile_3Dev = sorting::percentile(sortedSeries, nrValues, 0.27f, false); } availability.setText(QString::number((float)nrValues/(float)totDays * 100, 'f', 3)); average.setText(QString::number(avg, 'f', 1)); @@ -1626,7 +1628,7 @@ void Crit3DPointStatisticsWidget::showElaboration() float availab = ((float)validYears/(float)years.size())*100.0; availability.setText(QString::number(availab, 'f', 3)); - float mkendall = statisticalElab(mannKendall, NODATA, outputValues, outputValues.size(), meteoSettings->getRainfallThreshold()); + float mkendall = statisticalElab(mannKendall, NODATA, outputValues, int(outputValues.size()), meteoSettings->getRainfallThreshold()); significance.setText(QString::number(mkendall, 'f', 3)); float averageValue = sum/validYears; average.setText(QString::number(averageValue, 'f', 1)); @@ -1636,7 +1638,7 @@ void Crit3DPointStatisticsWidget::showElaboration() float myR2 = NODATA; bool isZeroIntercept = false; std::vector yearsFloat(years.begin(), years.end()); - statistics::linearRegression(yearsFloat, outputValues, outputValues.size(), isZeroIntercept, + statistics::linearRegression(yearsFloat, outputValues, int(outputValues.size()), isZeroIntercept, &myIntercept, &myCoeff, &myR2); r2.setText(QString::number(myR2, 'f', 3)); rate.setText(QString::number(myCoeff, 'f', 3)); diff --git a/project/project.cpp b/project/project.cpp index 57df6e6a..599c82c2 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -3429,6 +3429,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) QDate firstMonthlyDate = meteoGridDbHandler->getFirstMonthlytDate(); QDate lastMonthlyDate = meteoGridDbHandler->getLastMonthlyDate(); + logInfoGUI("Loading data...\n"); QDateTime firstDateTime, lastDateTime; if (meteoGridDbHandler->getFirstHourlyDate().isValid()) @@ -3454,8 +3455,6 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) if (isAppend) { - logInfoGUI("Loading data...\n"); - if (! meteoGridDbHandler->gridStructure().isFixedFields()) { if (meteoGridDbHandler->isDaily()) @@ -3464,6 +3463,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) } if (meteoGridDbHandler->isHourly()) { + logInfoGUI("Loading hourly data...\n"); meteoGridDbHandler->loadGridHourlyData(errorString, QString::fromStdString(idCell), firstDateTime, lastDateTime); } if (meteoGridDbHandler->isMonthly()) @@ -3479,6 +3479,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) } if (meteoGridDbHandler->isHourly()) { + logInfoGUI("Loading hourly data...\n"); meteoGridDbHandler->loadGridHourlyDataFixedFields(errorString, QString::fromStdString(idCell), firstDateTime, lastDateTime); } if (meteoGridDbHandler->isMonthly()) @@ -3506,7 +3507,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) { bool isGrid = true; Crit3DMeteoWidget* meteoWidgetGrid = new Crit3DMeteoWidget(isGrid, projectPath, meteoSettings); - if (!meteoWidgetGridList.isEmpty()) + if (! meteoWidgetGridList.isEmpty()) { meteoWidgetId = meteoWidgetGridList[meteoWidgetGridList.size()-1]->getMeteoWidgetID()+1; } @@ -3521,8 +3522,6 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) QObject::connect(meteoWidgetGrid, SIGNAL(closeWidgetGrid(int)), this, SLOT(deleteMeteoWidgetGrid(int))); - logInfoGUI("Loading data..."); - if (meteoGridDbHandler->gridStructure().isEnsemble()) { meteoWidgetGrid->setIsEnsemble(true); @@ -3557,7 +3556,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) } else { - if (!meteoGridDbHandler->gridStructure().isFixedFields()) + if (! meteoGridDbHandler->gridStructure().isFixedFields()) { if (meteoGridDbHandler->isDaily()) { @@ -3565,6 +3564,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) } if (meteoGridDbHandler->isHourly()) { + logInfoGUI("Loading hourly data...\n"); meteoGridDbHandler->loadGridHourlyData(errorString, QString::fromStdString(idCell), firstDateTime, lastDateTime); } if (meteoGridDbHandler->isMonthly()) @@ -3580,6 +3580,7 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) } if (meteoGridDbHandler->isHourly()) { + logInfoGUI("Loading hourly data...\n"); meteoGridDbHandler->loadGridHourlyDataFixedFields(errorString, QString::fromStdString(idCell), firstDateTime, lastDateTime); } if (meteoGridDbHandler->isMonthly()) @@ -3611,7 +3612,6 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) void Project::deleteMeteoWidgetPoint(int id) { - for (int i = 0; igetMeteoWidgetID() == id) @@ -4435,6 +4435,7 @@ void Project::logInfoGUI(QString myStr) formLog = new FormInfo(); } formLog->showInfo(myStr); + qApp->processEvents(); } else { From 6ae39a05f8204156f913881767e8746ab6be7971 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 21 Jun 2024 15:38:11 +0200 Subject: [PATCH 091/179] update meteoWidget --- meteo/meteo.cpp | 4 +- meteoWidget/meteoWidget.cpp | 321 ++++++++++++++++++++---------------- meteoWidget/meteoWidget.h | 100 +++++------ project/project.cpp | 25 +-- 4 files changed, 253 insertions(+), 197 deletions(-) diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index 53c327c1..6a9b1f88 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -944,9 +944,9 @@ std::string getKeyStringMeteoMap(std::map map, meteo return key; } + std::string getUnitFromVariable(meteoVariable var) { - std::string unit = ""; std::map, std::string>::const_iterator it; std::vector key; @@ -961,9 +961,11 @@ std::string getUnitFromVariable(meteoVariable var) } key.clear(); } + return unit; } + meteoVariable getKeyMeteoVarMeteoMap(std::map map, const std::string& value) { std::map::const_iterator it; diff --git a/meteoWidget/meteoWidget.cpp b/meteoWidget/meteoWidget.cpp index 17f19dee..e45b2b39 100644 --- a/meteoWidget/meteoWidget.cpp +++ b/meteoWidget/meteoWidget.cpp @@ -326,23 +326,23 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe axisX = new QBarCategoryAxis(); axisXvirtual = new QBarCategoryAxis(); - axisY = new QValueAxis(); - axisYdx = new QValueAxis(); + axisY_sx = new QValueAxis(); + axisY_dx = new QValueAxis(); axisX->setTitleText("Date"); axisXvirtual->setTitleText("Date"); axisXvirtual->setGridLineVisible(false); - axisY->setRange(0,30); - axisY->setGridLineVisible(false); + axisY_sx->setRange(0,30); + axisY_sx->setGridLineVisible(false); - axisYdx->setRange(0,8); - axisYdx->setGridLineVisible(false); + axisY_dx->setRange(0,8); + axisY_dx->setGridLineVisible(false); chart->addAxis(axisX, Qt::AlignBottom); chart->addAxis(axisXvirtual, Qt::AlignBottom); - chart->addAxis(axisY, Qt::AlignLeft); - chart->addAxis(axisYdx, Qt::AlignRight); + chart->addAxis(axisY_sx, Qt::AlignLeft); + chart->addAxis(axisY_dx, Qt::AlignRight); chart->legend()->setVisible(true); chart->legend()->setAlignment(Qt::AlignBottom); @@ -415,20 +415,20 @@ Crit3DMeteoWidget::~Crit3DMeteoWidget() } -void Crit3DMeteoWidget::setDateIntervalDaily(QDate firstDate, QDate lastDate) +void Crit3DMeteoWidget::setDailyRange(QDate firstDate, QDate lastDate) { firstDailyDate = firstDate; lastDailyDate = lastDate; } -void Crit3DMeteoWidget::setDateIntervalHourly(QDate firstDate, QDate lastDate) +void Crit3DMeteoWidget::setHourlyRange(QDate firstDate, QDate lastDate) { firstHourlyDate = firstDate; lastHourlyDate = lastDate; } -void Crit3DMeteoWidget::setDateIntervalMonthly(QDate firstDate, QDate lastDate) +void Crit3DMeteoWidget::setMonthlyRange(QDate firstDate, QDate lastDate) { firstMonthlyDate = firstDate; lastMonthlyDate = lastDate; @@ -628,13 +628,16 @@ void Crit3DMeteoWidget::drawEnsemble() { lastDailyDate = myDailyDateLast; } + myHourlyDateFirst.setDate(meteoPointsEnsemble[0].getMeteoPointHourlyValuesDate(0).year, meteoPointsEnsemble[0].getMeteoPointHourlyValuesDate(0).month, meteoPointsEnsemble[0].getMeteoPointHourlyValuesDate(0).day); myHourlyDateLast = myHourlyDateFirst.addDays(meteoPointsEnsemble[0].nrObsDataDaysH-1); + if (myHourlyDateFirst.isValid() && myHourlyDateFirst < firstHourlyDate) { firstHourlyDate = myHourlyDateFirst; } + if (myHourlyDateLast.isValid() && myHourlyDateLast > lastHourlyDate) { lastHourlyDate = myHourlyDateLast; @@ -926,7 +929,7 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() categories.append(QString::number(day)); } - QList sortedList; + std::vector sortedList; QList listBoxSet; if (isLine) @@ -952,7 +955,7 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() double value = meteoPointsEnsemble[mp].getMeteoPointValueD(myDate, meteoVar, meteoSettings); if (value != NODATA) { - sortedList.append(value); + sortedList.push_back(value); if (value > maxEnsembleLine) { maxEnsembleLine = value; @@ -964,15 +967,15 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() } } QBoxSet *box = new QBoxSet(); - if (!sortedList.isEmpty()) + if (! sortedList.empty()) { std::sort(sortedList.begin(), sortedList.end()); - int count = sortedList.count(); - box->setValue(QBoxSet::LowerExtreme, sortedList.first()); - box->setValue(QBoxSet::UpperExtreme, sortedList.last()); - box->setValue(QBoxSet::Median, findMedian(sortedList, 0, count)); - box->setValue(QBoxSet::LowerQuartile, findMedian(sortedList, 0, count / 2)); - box->setValue(QBoxSet::UpperQuartile, findMedian(sortedList, count / 2 + (count % 2), count)); + int lastIndex = int(sortedList.size())-1; + box->setValue(QBoxSet::LowerExtreme, sortedList.front()); + box->setValue(QBoxSet::UpperExtreme, sortedList.back()); + box->setValue(QBoxSet::Median, findMedian(sortedList, 0, lastIndex)); + box->setValue(QBoxSet::LowerQuartile, findMedian(sortedList, 0, lastIndex / 2)); + box->setValue(QBoxSet::UpperQuartile, findMedian(sortedList, lastIndex / 2 + (lastIndex % 2), lastIndex)); } else { @@ -992,7 +995,7 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() ensembleSeries.append(series); chart->addSeries(series); series->attachAxis(axisX); - series->attachAxis(axisY); + series->attachAxis(axisY_sx); } } } @@ -1019,7 +1022,7 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() double value = meteoPointsEnsemble[mp].getMeteoPointValueD(myDate, meteoVar, meteoSettings); if (value != NODATA) { - sortedList.append(value); + sortedList.push_back(value); if (value > maxEnsembleBar) { maxEnsembleBar = value; @@ -1027,15 +1030,15 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() } } QBoxSet *box = new QBoxSet(); - if (!sortedList.isEmpty()) + if (! sortedList.empty()) { std::sort(sortedList.begin(), sortedList.end()); - int count = sortedList.count(); - box->setValue(QBoxSet::LowerExtreme, sortedList.first()); - box->setValue(QBoxSet::UpperExtreme, sortedList.last()); - box->setValue(QBoxSet::Median, findMedian(sortedList, 0, count)); - box->setValue(QBoxSet::LowerQuartile, findMedian(sortedList, 0, count / 2)); - box->setValue(QBoxSet::UpperQuartile, findMedian(sortedList, count / 2 + (count % 2), count)); + int lastIndex = int(sortedList.size())-1; + box->setValue(QBoxSet::LowerExtreme, sortedList.front()); + box->setValue(QBoxSet::UpperExtreme, sortedList.back()); + box->setValue(QBoxSet::Median, findMedian(sortedList, 0, lastIndex)); + box->setValue(QBoxSet::LowerQuartile, findMedian(sortedList, 0, lastIndex / 2)); + box->setValue(QBoxSet::UpperQuartile, findMedian(sortedList, lastIndex / 2 + (lastIndex % 2), lastIndex)); } else { @@ -1055,7 +1058,7 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() ensembleSeries.append(series); chart->addSeries(series); series->attachAxis(axisX); - series->attachAxis(axisYdx); + series->attachAxis(axisY_dx); } } } @@ -1064,62 +1067,123 @@ void Crit3DMeteoWidget::drawEnsembleDailyVar() { if (maxEnsembleLine == NODATA && minEnsembleLine == -NODATA) { - axisY->setVisible(false); + axisY_sx->setVisible(false); } else { - axisY->setVisible(true); - axisY->setMax(maxEnsembleLine); - axisY->setMin(minEnsembleLine); - if (axisY->max() == axisY->min()) + axisY_sx->setVisible(true); + axisY_sx->setMax(maxEnsembleLine); + axisY_sx->setMin(minEnsembleLine); + if (axisY_sx->max() == axisY_sx->min()) { - axisY->setRange(axisY->min()-axisY->min()/100, axisY->max()+axisY->max()/100); + axisY_sx->setRange(axisY_sx->min()-axisY_sx->min()/100, axisY_sx->max()+axisY_sx->max()/100); } } } else { - axisY->setVisible(false); + axisY_sx->setVisible(false); } if (isBar) { if (maxEnsembleBar == -1) { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } else { - axisYdx->setVisible(true); + axisY_dx->setVisible(true); if (maxEnsembleBar != 0) { - axisYdx->setRange(0,maxEnsembleBar); + axisY_dx->setRange(0,maxEnsembleBar); } else { - axisYdx->setRange(0,1); + axisY_dx->setRange(0,1); } } } else { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } axisX->setCategories(categories); axisXvirtual->setCategories(categoriesVirtual); axisXvirtual->setGridLineVisible(false); + drawAxisTitle(); + formInfo.close(); + firstDate->blockSignals(false); lastDate->blockSignals(false); +} - formInfo.close(); + +void Crit3DMeteoWidget::drawAxisTitle() +{ + if (! isInitialized) + return; + + QList unitList; + QString axisTitle = ""; + + // axis sx (lines) + for (int i = 0; i < nameLines.size(); i++) + { + meteoVariable meteoVar = getMeteoVar(nameLines[i].toStdString()); + QString unitStr = QString::fromStdString(getUnitFromVariable(meteoVar)); + if (! unitList.contains(unitStr)) + { + unitList.append(unitStr); + } + } + + if (! unitList.empty()) + { + for (int i = 0; i < unitList.size(); i++) + { + if (i > 0) + axisTitle += " , "; + + axisTitle += unitList[i]; + } + } + axisY_sx->setTitleText(axisTitle); + + // axis dx (bar) + unitList.clear(); + for (int i = 0; i < nameBar.size(); i++) + { + meteoVariable meteoVar = getMeteoVar(nameBar[i].toStdString()); + QString unitStr = QString::fromStdString(getUnitFromVariable(meteoVar)); + if (! unitList.contains(unitStr)) + { + unitList.append(unitStr); + } + } + + axisTitle.clear(); + if (! unitList.empty()) + { + for (int i = 0; i < unitList.size(); i++) + { + if (i > 0) + axisTitle += " , "; + + axisTitle += unitList[i]; + } + } + + axisY_dx->setTitleText(axisTitle); } void Crit3DMeteoWidget::drawDailyVar() { - if (! isInitialized) return; + if (! isInitialized) + return; FormInfo formInfo; formInfo.showInfo("Draw daily data..."); @@ -1202,7 +1266,8 @@ void Crit3DMeteoWidget::drawDailyVar() { if (meteoPoints[mp].isDateLoadedD(myDate)) { - lineSeries[mp][i]->append(day, value); // nodata days are not drawed if they are the first of the last day of the serie + // nodata days are not drawed if they are the first of the last day of the series + lineSeries[mp][i]->append(day, value); } } } @@ -1254,33 +1319,33 @@ void Crit3DMeteoWidget::drawDailyVar() { chart->addSeries(barSeries[mp]); barSeries[mp]->attachAxis(axisX); - barSeries[mp]->attachAxis(axisYdx); + barSeries[mp]->attachAxis(axisY_dx); } } if (maxEnsembleBar == -1 && maxBar == -1) { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } else { - axisYdx->setVisible(true); + axisY_dx->setVisible(true); if (maxEnsembleBar > maxBar) { - axisYdx->setRange(0,maxEnsembleBar); + axisY_dx->setRange(0,maxEnsembleBar); } else { - axisYdx->setRange(0,maxBar); + axisY_dx->setRange(0,maxBar); } - if (axisYdx->max() == axisYdx->min()) + if (axisY_dx->max() == axisY_dx->min()) { - axisYdx->setRange(0,1); + axisY_dx->setRange(0,1); } } } else { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } if (isLine) @@ -1293,7 +1358,7 @@ void Crit3DMeteoWidget::drawDailyVar() { chart->addSeries(lineSeries[mp][i]); lineSeries[mp][i]->attachAxis(axisX); - lineSeries[mp][i]->attachAxis(axisY); + lineSeries[mp][i]->attachAxis(axisY_sx); connect(lineSeries[mp][i], &QLineSeries::hovered, this, &Crit3DMeteoWidget::tooltipLineSeries); connect(lineSeries[mp][i], &QLineSeries::clicked, this, &Crit3DMeteoWidget::editLineSeries); } @@ -1301,41 +1366,41 @@ void Crit3DMeteoWidget::drawDailyVar() } if (maxLine == NODATA && minLine == -NODATA && maxEnsembleLine == NODATA && minEnsembleLine == -NODATA) { - axisY->setVisible(false); + axisY_sx->setVisible(false); } else { - axisY->setVisible(true); + axisY_sx->setVisible(true); if (maxEnsembleLine > maxLine) { - axisY->setMax(maxEnsembleLine); + axisY_sx->setMax(maxEnsembleLine); } else { - axisY->setMax(maxLine); + axisY_sx->setMax(maxLine); } if (minEnsembleLine < minLine) { - axisY->setMin(minEnsembleLine); + axisY_sx->setMin(minEnsembleLine); } else { - axisY->setMin(minLine); + axisY_sx->setMin(minLine); } - if (axisY->max() == axisY->min()) + if (axisY_sx->max() == axisY_sx->min()) { - axisY->setRange(axisY->min()-axisY->min()/100, axisY->max()+axisY->max()/100); + axisY_sx->setRange(axisY_sx->min()-axisY_sx->min()/100, axisY_sx->max()+axisY_sx->max()/100); } } } else { - axisY->setVisible(false); + axisY_sx->setVisible(false); } // add zeroLine - if (axisY->min() <= 0 && axisY->max() >= 0) + if (axisY_sx->min() <= 0 && axisY_sx->max() >= 0) { zeroLine->clear(); for (int day = 0; day < nDays; day++) @@ -1344,7 +1409,7 @@ void Crit3DMeteoWidget::drawDailyVar() } chart->addSeries(zeroLine); zeroLine->attachAxis(axisX); - zeroLine->attachAxis(axisY); + zeroLine->attachAxis(axisY_sx); } // add minimimum values required @@ -1405,7 +1470,7 @@ void Crit3DMeteoWidget::drawDailyVar() } } - + drawAxisTitle(); formInfo.close(); } @@ -1556,29 +1621,29 @@ void Crit3DMeteoWidget::drawHourlyVar() { chart->addSeries(barSeries[mp]); barSeries[mp]->attachAxis(axisX); - barSeries[mp]->attachAxis(axisYdx); + barSeries[mp]->attachAxis(axisY_dx); } } if (maxBar == -1) { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } else { - axisYdx->setVisible(true); + axisY_dx->setVisible(true); if (maxBar != 0) { - axisYdx->setRange(0,maxBar); + axisY_dx->setRange(0,maxBar); } else { - axisYdx->setRange(0,1); + axisY_dx->setRange(0,1); } } } else { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } if (isLine) @@ -1589,34 +1654,34 @@ void Crit3DMeteoWidget::drawHourlyVar() { chart->addSeries(lineSeries[mp][i]); lineSeries[mp][i]->attachAxis(axisX); - lineSeries[mp][i]->attachAxis(axisY); + lineSeries[mp][i]->attachAxis(axisY_sx); connect(lineSeries[mp][i], &QLineSeries::hovered, this, &Crit3DMeteoWidget::tooltipLineSeries); connect(lineSeries[mp][i], &QLineSeries::clicked, this, &Crit3DMeteoWidget::editLineSeries); } } if (maxLine == NODATA && minLine == -NODATA) { - axisY->setVisible(false); + axisY_sx->setVisible(false); } else { - axisY->setVisible(true); - axisY->setMax(maxLine); - axisY->setMin(minLine); + axisY_sx->setVisible(true); + axisY_sx->setMax(maxLine); + axisY_sx->setMin(minLine); - if (axisY->max() == axisY->min()) + if (axisY_sx->max() == axisY_sx->min()) { - axisY->setRange(axisY->min()-axisY->min()/100, axisY->max()+axisY->max()/100); + axisY_sx->setRange(axisY_sx->min()-axisY_sx->min()/100, axisY_sx->max()+axisY_sx->max()/100); } } } else { - axisY->setVisible(false); + axisY_sx->setVisible(false); } // add zeroLine - if (axisY->min() <= 0 && axisY->max() >= 0) + if (axisY_sx->min() <= 0 && axisY_sx->max() >= 0) { zeroLine->clear(); for (int d = 0; d < nDays; d++) @@ -1629,7 +1694,7 @@ void Crit3DMeteoWidget::drawHourlyVar() } chart->addSeries(zeroLine); zeroLine->attachAxis(axisX); - zeroLine->attachAxis(axisY); + zeroLine->attachAxis(axisY_sx); } axisX->setCategories(categories); @@ -1654,9 +1719,11 @@ void Crit3DMeteoWidget::drawHourlyVar() } } + drawAxisTitle(); formInfo.close(); } + void Crit3DMeteoWidget::drawMonthlyVar() { if (! isInitialized) return; @@ -1791,33 +1858,33 @@ void Crit3DMeteoWidget::drawMonthlyVar() { chart->addSeries(barSeries[mp]); barSeries[mp]->attachAxis(axisX); - barSeries[mp]->attachAxis(axisYdx); + barSeries[mp]->attachAxis(axisY_dx); } } if (maxEnsembleBar == -1 && maxBar == -1) { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } else { - axisYdx->setVisible(true); + axisY_dx->setVisible(true); if (maxEnsembleBar > maxBar) { - axisYdx->setRange(0,maxEnsembleBar); + axisY_dx->setRange(0,maxEnsembleBar); } else { - axisYdx->setRange(0,maxBar); + axisY_dx->setRange(0,maxBar); } - if (axisYdx->max() == axisYdx->min()) + if (axisY_dx->max() == axisY_dx->min()) { - axisYdx->setRange(0,1); + axisY_dx->setRange(0,1); } } } else { - axisYdx->setVisible(false); + axisY_dx->setVisible(false); } if (isLine) @@ -1830,7 +1897,7 @@ void Crit3DMeteoWidget::drawMonthlyVar() { chart->addSeries(lineSeries[mp][i]); lineSeries[mp][i]->attachAxis(axisX); - lineSeries[mp][i]->attachAxis(axisY); + lineSeries[mp][i]->attachAxis(axisY_sx); connect(lineSeries[mp][i], &QLineSeries::hovered, this, &Crit3DMeteoWidget::tooltipLineSeries); connect(lineSeries[mp][i], &QLineSeries::clicked, this, &Crit3DMeteoWidget::editLineSeries); } @@ -1838,41 +1905,41 @@ void Crit3DMeteoWidget::drawMonthlyVar() } if (maxLine == NODATA && minLine == -NODATA && maxEnsembleLine == NODATA && minEnsembleLine == -NODATA) { - axisY->setVisible(false); + axisY_sx->setVisible(false); } else { - axisY->setVisible(true); + axisY_sx->setVisible(true); if (maxEnsembleLine > maxLine) { - axisY->setMax(maxEnsembleLine); + axisY_sx->setMax(maxEnsembleLine); } else { - axisY->setMax(maxLine); + axisY_sx->setMax(maxLine); } if (minEnsembleLine < minLine) { - axisY->setMin(minEnsembleLine); + axisY_sx->setMin(minEnsembleLine); } else { - axisY->setMin(minLine); + axisY_sx->setMin(minLine); } - if (axisY->max() == axisY->min()) + if (axisY_sx->max() == axisY_sx->min()) { - axisY->setRange(axisY->min()-axisY->min()/100, axisY->max()+axisY->max()/100); + axisY_sx->setRange(axisY_sx->min()-axisY_sx->min()/100, axisY_sx->max()+axisY_sx->max()/100); } } } else { - axisY->setVisible(false); + axisY_sx->setVisible(false); } // add zeroLine - if (axisY->min() <= 0 && axisY->max() >= 0) + if (axisY_sx->min() <= 0 && axisY_sx->max() >= 0) { zeroLine->clear(); for (int month = 0; month < numberOfMonths; month++) @@ -1881,7 +1948,7 @@ void Crit3DMeteoWidget::drawMonthlyVar() } chart->addSeries(zeroLine); zeroLine->attachAxis(axisX); - zeroLine->attachAxis(axisY); + zeroLine->attachAxis(axisY_sx); } // add minimimum values required @@ -1942,6 +2009,7 @@ void Crit3DMeteoWidget::drawMonthlyVar() } } + drawAxisTitle(); formInfo.close(); } @@ -2325,7 +2393,6 @@ void Crit3DMeteoWidget::redraw() } } } - } @@ -2895,38 +2962,14 @@ void Crit3DMeteoWidget::setIsEnsemble(bool value) tableButton->setEnabled(!value); } -bool Crit3DMeteoWidget::getIsEnsemble() -{ - return isEnsemble; -} - -void Crit3DMeteoWidget::setNrMembers(int value) -{ - nrMembers = value; -} - -int Crit3DMeteoWidget::getMeteoWidgetID() const -{ - return meteoWidgetID; -} - -void Crit3DMeteoWidget::setMeteoWidgetID(int value) -{ - meteoWidgetID = value; -} - -void Crit3DMeteoWidget::setCurrentDate(QDate myDate) -{ - currentDate = myDate; -} void Crit3DMeteoWidget::on_actionChangeLeftAxis() { DialogChangeAxis changeAxisDialog(true); if (changeAxisDialog.result() == QDialog::Accepted) { - axisY->setMax(changeAxisDialog.getMaxVal()); - axisY->setMin(changeAxisDialog.getMinVal()); + axisY_sx->setMax(changeAxisDialog.getMaxVal()); + axisY_sx->setMin(changeAxisDialog.getMinVal()); } } @@ -2936,8 +2979,8 @@ void Crit3DMeteoWidget::on_actionChangeRightAxis() DialogChangeAxis changeAxisDialog(false); if (changeAxisDialog.result() == QDialog::Accepted) { - axisYdx->setMax(changeAxisDialog.getMaxVal()); - axisYdx->setMin(changeAxisDialog.getMinVal()); + axisY_dx->setMax(changeAxisDialog.getMaxVal()); + axisY_dx->setMin(changeAxisDialog.getMinVal()); } } @@ -3206,7 +3249,7 @@ void Crit3DMeteoWidget::drawSum() cumulativePoints.clear(); } } - axisY->setRange(axisY->min(),max); + axisY_sx->setRange(axisY_sx->min(),max); } } if (! barSeries.isEmpty()) @@ -3238,24 +3281,24 @@ void Crit3DMeteoWidget::drawSum() cumulativeValues.clear(); } } - axisYdx->setRange(axisYdx->min(),max); + axisY_dx->setRange(axisY_dx->min(),max); } } } } -qreal findMedian(QList sortedList, int begin, int end) +qreal findMedian(std::vector sortedList, int begin, int end) { int count = end - begin; - if (count % 2) { + if (count % 2) + { return sortedList.at(count / 2 + begin); - } else { + } + else + { qreal right = sortedList.at(count / 2 + begin); qreal left = sortedList.at(count / 2 - 1 + begin); return (right + left) / 2.0; } } - - - diff --git a/meteoWidget/meteoWidget.h b/meteoWidget/meteoWidget.h index 39c878c0..447bc5c8 100644 --- a/meteoWidget/meteoWidget.h +++ b/meteoWidget/meteoWidget.h @@ -7,8 +7,6 @@ #include "meteoPoint.h" #include "callout.h" - qreal findMedian(QList sortedList, int begin, int end); - class Crit3DMeteoWidget : public QWidget { Q_OBJECT @@ -17,55 +15,24 @@ Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMeteoSettings* meteoSettings_); ~Crit3DMeteoWidget() override; - int getMeteoWidgetID() const; - void setMeteoWidgetID(int value); + int getMeteoWidgetID() const { return meteoWidgetID; } + void setMeteoWidgetID(int value) { meteoWidgetID = value; } + + void setCurrentDate(QDate myDate) { currentDate = myDate; } - void setCurrentDate(QDate myDate); - void setDateIntervalDaily(QDate firstDate, QDate lastDate); - void setDateIntervalHourly(QDate firstDate, QDate lastDate); - void setDateIntervalMonthly(QDate firstDate, QDate lastDate); + void setIsEnsemble(bool value); + bool getIsEnsemble() { return isEnsemble; } + void setNrMembers(int value) { nrMembers = value; } + + void setDailyRange(QDate firstDate, QDate lastDate); + void setHourlyRange(QDate firstDate, QDate lastDate); + void setMonthlyRange(QDate firstDate, QDate lastDate); void addMeteoPointsEnsemble(Crit3DMeteoPoint mp); - void updateTimeRange(); void drawMeteoPoint(Crit3DMeteoPoint mp, bool isAppend); void drawEnsemble(); - void resetValues(); - void resetEnsembleValues(); - void drawDailyVar(); - void drawEnsembleDailyVar(); - void drawHourlyVar(); - void drawMonthlyVar(); - void showMonthlyGraph(); - void showDailyGraph(); - void showHourlyGraph(); - void updateSeries(); - void redraw(); - void shiftPrevious(); - void shiftFollowing(); - void showTable(); - void showVar(); - void tooltipLineSeries(QPointF point, bool state); - void editLineSeries(); - bool computeTooltipLineSeries(QLineSeries *series, QPointF point, bool state); - void tooltipBar(bool state, int index, QBarSet *barset); - void editBar(); - void handleMarkerClicked(); - void closeEvent(QCloseEvent *event) override; - void setIsEnsemble(bool value); - bool getIsEnsemble(); - void setNrMembers(int value); - void on_actionChangeLeftAxis(); - void on_actionChangeRightAxis(); - void on_actionExportGraph(); - void on_actionRemoveStation(); - void on_actionInfoPoint(); - void on_actionDataAvailability(); - void on_actionDataSum(); - void drawSum(); - void checkExistingData(); - private: int meteoWidgetID; bool isGrid; @@ -101,8 +68,8 @@ QChart *chart; QBarCategoryAxis *axisX; QBarCategoryAxis *axisXvirtual; - QValueAxis *axisY; - QValueAxis *axisYdx; + QValueAxis *axisY_sx; + QValueAxis *axisY_dx; QMap> MapCSVDefault; QMap> MapCSVStyles; QList currentVariables; @@ -128,6 +95,44 @@ bool isLine; bool isBar; Callout *m_tooltip; + + void updateTimeRange(); + void resetValues(); + void resetEnsembleValues(); + void drawDailyVar(); + void drawEnsembleDailyVar(); + void drawHourlyVar(); + void drawMonthlyVar(); + void showMonthlyGraph(); + void showDailyGraph(); + void showHourlyGraph(); + void updateSeries(); + void redraw(); + void shiftPrevious(); + void shiftFollowing(); + void showTable(); + void showVar(); + void tooltipLineSeries(QPointF point, bool state); + void editLineSeries(); + bool computeTooltipLineSeries(QLineSeries *series, QPointF point, bool state); + void tooltipBar(bool state, int index, QBarSet *barset); + void editBar(); + void handleMarkerClicked(); + void closeEvent(QCloseEvent *event) override; + + void on_actionChangeLeftAxis(); + void on_actionChangeRightAxis(); + void on_actionExportGraph(); + void on_actionRemoveStation(); + void on_actionInfoPoint(); + void on_actionDataAvailability(); + void on_actionDataSum(); + + void drawAxisTitle(); + void drawSum(); + void checkExistingData(); + + signals: void closeWidgetPoint(int); void closeWidgetGrid(int); @@ -135,4 +140,7 @@ }; + qreal findMedian(std::vector sortedList, int begin, int end); + + #endif // METEOWIDGET_H diff --git a/project/project.cpp b/project/project.cpp index 599c82c2..77444758 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -3407,11 +3407,11 @@ void Project::showMeteoWidgetPoint(std::string idMeteoPoint, std::string namePoi if (hasDailyData) { - meteoWidgetPoint->setDateIntervalDaily(firstDaily, lastDaily); + meteoWidgetPoint->setDailyRange(firstDaily, lastDaily); } if (hasHourlyData) { - meteoWidgetPoint->setDateIntervalHourly(firstHourly.date(), lastHourly.date()); + meteoWidgetPoint->setHourlyRange(firstHourly.date(), lastHourly.date()); } meteoWidgetPoint->setCurrentDate(this->currentDate); @@ -3429,8 +3429,6 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) QDate firstMonthlyDate = meteoGridDbHandler->getFirstMonthlytDate(); QDate lastMonthlyDate = meteoGridDbHandler->getLastMonthlyDate(); - logInfoGUI("Loading data...\n"); - QDateTime firstDateTime, lastDateTime; if (meteoGridDbHandler->getFirstHourlyDate().isValid()) { @@ -3442,17 +3440,22 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) } int meteoWidgetId = 0; - if (meteoWidgetGridList.isEmpty() || meteoGridDbHandler->gridStructure().isEnsemble()) + if (meteoWidgetGridList.isEmpty()) { isAppend = false; } if (meteoGridDbHandler->gridStructure().isEnsemble()) { - isAppend = false; - logInfoGUI("Meteo grid is ensemble: append mode is not possible, a new widget is opening."); + if (isAppend) + { + isAppend = false; + logWarning("Meteo grid is ensemble: append mode is not possible.\nA new meteo widget will be open."); + } } + logInfoGUI("Loading data...\n"); + if (isAppend) { if (! meteoGridDbHandler->gridStructure().isFixedFields()) @@ -3533,11 +3536,11 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) { if (meteoGridDbHandler->isDaily()) { - meteoWidgetGrid->setDateIntervalDaily(firstDate, lastDate); + meteoWidgetGrid->setDailyRange(firstDate, lastDate); } if (meteoGridDbHandler->isHourly()) { - meteoWidgetGrid->setDateIntervalHourly(firstDateTime.date(), lastDateTime.date()); + meteoWidgetGrid->setHourlyRange(firstDateTime.date(), lastDateTime.date()); } } else @@ -3595,11 +3598,11 @@ void Project::showMeteoWidgetGrid(std::string idCell, bool isAppend) { if (meteoGridDbHandler->isDaily()) { - meteoWidgetGrid->setDateIntervalDaily(firstDate, lastDate); + meteoWidgetGrid->setDailyRange(firstDate, lastDate); } if (meteoGridDbHandler->isHourly()) { - meteoWidgetGrid->setDateIntervalHourly(firstDateTime.date(), lastDateTime.date()); + meteoWidgetGrid->setHourlyRange(firstDateTime.date(), lastDateTime.date()); } meteoWidgetGrid->drawMeteoPoint(meteoGridDbHandler->meteoGrid()->meteoPoint(row,col), isAppend); From e47ec43a3b267e798f6203850b274913b18678d9 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 21 Jun 2024 18:05:58 +0200 Subject: [PATCH 092/179] update criteria3D --- soil/soil.cpp | 2 +- soil/soilDbTools.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/soil/soil.cpp b/soil/soil.cpp index f461172d..b6a0d53c 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -814,7 +814,7 @@ namespace soil horizon.texture.silt = horizon.dbData.silt; horizon.texture.clay = horizon.dbData.clay; if (! isEqual(horizon.texture.sand, NODATA) && ! isEqual(horizon.texture.silt, NODATA) && ! isEqual(horizon.texture.clay, NODATA) - && (horizon.texture.sand + horizon.texture.silt + horizon.texture.clay) <= 1 ) + && (horizon.texture.sand + horizon.texture.silt + horizon.texture.clay) <= 1.01 ) { horizon.texture.sand *= 100; horizon.texture.silt *= 100; diff --git a/soil/soilDbTools.cpp b/soil/soilDbTools.cpp index 06fd0a3a..b4c6885a 100644 --- a/soil/soilDbTools.cpp +++ b/soil/soilDbTools.cpp @@ -1,6 +1,7 @@ #include "soil.h" #include "soilDbTools.h" #include "commonConstants.h" +#include "basicMath.h" #include "utilities.h" #include @@ -275,6 +276,13 @@ bool loadSoilData(const QSqlDatabase &dbSoil, const QString &soilCode, soil::Cri getValue(query.value("sand"), &sand); getValue(query.value("silt"), &silt); getValue(query.value("clay"), &clay); + // check + if (! isEqual(sand, NODATA) && ! isEqual(silt, NODATA) && ! isEqual(clay, NODATA) && (sand + silt + clay) <= 1.01) + { + sand *= 100; + silt *= 100; + clay *= 100; + } mySoil.horizon[i].dbData.sand = sand; mySoil.horizon[i].dbData.silt = silt; mySoil.horizon[i].dbData.clay = clay; From c71f4fe26be4bc0abd9d0b35210d042299c0ff3f Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 24 Jun 2024 17:42:04 +0200 Subject: [PATCH 093/179] output shell --- project/shell.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/project/shell.cpp b/project/shell.cpp index b80e0521..b208d44e 100644 --- a/project/shell.cpp +++ b/project/shell.cpp @@ -382,6 +382,14 @@ int cmdExportDailyDataCsv(Project* myProject, QList argumentList) QString completeOutputPath = myProject->getProjectPath() + outputPath; outputPath = QDir().cleanPath(completeOutputPath); } + else + { + if(getFileName(outputPath) == outputPath) + { + QString completeOutputPath = myProject->getProjectPath() + PATH_OUTPUT + outputPath; + outputPath = QDir().cleanPath(completeOutputPath); + } + } } } } From 0c5aa9b68511c42944f67d791c53efec6b69a374 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 24 Jun 2024 17:43:33 +0200 Subject: [PATCH 094/179] fix shell --- project/shell.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/project/shell.cpp b/project/shell.cpp index b208d44e..9230ddcc 100644 --- a/project/shell.cpp +++ b/project/shell.cpp @@ -3,6 +3,7 @@ #include "project.h" #include "shell.h" #include "dbMeteoGrid.h" +#include "utilities.h" #include #include From 84f8d32bf81547cfe9ec6625d6f4098651041a5e Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 24 Jun 2024 19:15:39 +0200 Subject: [PATCH 095/179] fix download --- dbMeteoPoints/dbMeteoPointsHandler.cpp | 30 ++++++++------- dbMeteoPoints/dbMeteoPointsHandler.h | 2 +- dbMeteoPoints/download.cpp | 51 ++++++++++++++++++-------- dbMeteoPoints/download.h | 8 +++- pragaProject/pragaProject.cpp | 14 +++++-- 5 files changed, 69 insertions(+), 36 deletions(-) diff --git a/dbMeteoPoints/dbMeteoPointsHandler.cpp b/dbMeteoPoints/dbMeteoPointsHandler.cpp index 851af863..de82441f 100644 --- a/dbMeteoPoints/dbMeteoPointsHandler.cpp +++ b/dbMeteoPoints/dbMeteoPointsHandler.cpp @@ -76,28 +76,32 @@ Crit3DMeteoPointsDbHandler::~Crit3DMeteoPointsDbHandler() } -QString Crit3DMeteoPointsDbHandler::getDatasetURL(QString dataset) +QString Crit3DMeteoPointsDbHandler::getDatasetURL(QString dataset, bool &isOk) { - QSqlQuery qry(_db); - QString url = nullptr; - - qry.prepare( "SELECT URL FROM datasets WHERE dataset = :dataset"); - qry.bindValue(":dataset", dataset); + errorStr = ""; + QString queryStr = QString("SELECT URL FROM datasets WHERE dataset = '%1' OR dataset = '%2'").arg(dataset, dataset.toUpper()); - if( !qry.exec() ) + QSqlQuery qry(_db); + if(! qry.exec(queryStr)) { - qDebug() << qry.lastError(); + isOk = false; + errorStr = qry.lastError().text(); + return ""; } else { if (qry.next()) - url = qry.value(0).toString(); - + { + isOk = true; + return qry.value(0).toString(); + } else - qDebug( "Error: dataset not found" ); + { + isOk = false; + errorStr = "dataset " + dataset + " not found in the table 'datasets'"; + return ""; + } } - - return url; } diff --git a/dbMeteoPoints/dbMeteoPointsHandler.h b/dbMeteoPoints/dbMeteoPointsHandler.h index e159561b..43c859f8 100644 --- a/dbMeteoPoints/dbMeteoPointsHandler.h +++ b/dbMeteoPoints/dbMeteoPointsHandler.h @@ -40,7 +40,7 @@ QString getErrorString() { return errorStr; } void setErrorString(QString str) { errorStr = str; } - QString getDatasetURL(QString dataset); + QString getDatasetURL(QString dataset, bool &isOk); bool setAndOpenDb(QString dbname_); QList getAllDatasetsList(); diff --git a/dbMeteoPoints/download.cpp b/dbMeteoPoints/download.cpp index 379d6919..65d1e0a7 100644 --- a/dbMeteoPoints/download.cpp +++ b/dbMeteoPoints/download.cpp @@ -1,4 +1,5 @@ #include "download.h" +#include "dbMeteoPointsHandler.h" #include @@ -258,9 +259,9 @@ void Download::downloadMetadata(QJsonObject obj) _dbMeteo->writePointProperties(pointProp); } + bool Download::getPointPropertiesFromId(QString id, Crit3DMeteoPoint* pointProp) { - bool result = true; QEventLoop loop; @@ -291,7 +292,7 @@ bool Download::getPointPropertiesFromId(QString id, Crit3DMeteoPoint* pointProp) qDebug() << "err: " << error->errorString() << " -> " << error->offset; // check validity of the document - if(!doc.isNull() && doc.isArray()) + if(! doc.isNull() && doc.isArray()) { QJsonArray jsonArr = doc.array(); @@ -392,7 +393,8 @@ bool Download::getPointPropertiesFromId(QString id, Crit3DMeteoPoint* pointProp) } -bool Download::downloadDailyData(QDate startDate, QDate endDate, QString dataset, QList stations, QList variables, bool prec0024) +bool Download::downloadDailyData(const QDate &startDate, const QDate &endDate, const QString &dataset, + QList &stations, QList &variables, bool prec0024, QString &errorString) { QString area, product, refTime; QDate myDate; @@ -403,13 +405,15 @@ bool Download::downloadDailyData(QDate startDate, QDate endDate, QString dataset QList idVar; for (int i = 0; i < variableList.size(); i++) + { idVar.append(QString::number(variableList[i].id())); + } // create station tables _dbMeteo->initStationsDailyTables(startDate, endDate, stations, idVar); // attenzione: il reference time dei giornalieri รจ a fine giornata (ore 00 di day+1) - refTime = QString("reftime:>%1,<=%2").arg(startDate.toString("yyyy-MM-dd")).arg(endDate.addDays(1).toString("yyyy-MM-dd")); + refTime = QString("reftime:>%1,<=%2").arg(startDate.toString("yyyy-MM-dd"), endDate.addDays(1).toString("yyyy-MM-dd")); product = QString(";product: VM2,%1").arg(variables[0]); @@ -432,20 +436,27 @@ bool Download::downloadDailyData(QDate startDate, QDate endDate, QString dataset if (j == 0) { area = QString(";area: VM2,%1").arg(stations[countStation]); - j = j+1; - countStation = countStation+1; + countStation++; + j++; } while (countStation < stations.size() && j < maxStationSize) { area = area % QString(" or VM2,%1").arg(stations[countStation]); - countStation = countStation+1; - j = j+1; + countStation++; + j++; + } + + bool isOk; + url = QUrl(QString("%1/query").arg(_dbMeteo->getDatasetURL(dataset, isOk))); + if (! isOk) + { + errorString = _dbMeteo->getErrorString(); + return false; } QNetworkAccessManager* manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit())); - url = QUrl(QString("%1/query").arg(_dbMeteo->getDatasetURL(dataset))); request.setUrl(url); request.setRawHeader("Authorization", _authorization); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); @@ -460,7 +471,7 @@ bool Download::downloadDailyData(QDate startDate, QDate endDate, QString dataset if (reply->error() != QNetworkReply::NoError) { - qDebug( "Network Error" ); + errorString = "Network Error"; downloadOk = false; } else @@ -515,7 +526,7 @@ bool Download::downloadDailyData(QDate startDate, QDate endDate, QString dataset } } - if (!emptyLine) + if (! emptyLine) { downloadOk = _dbMeteo->saveDailyData(); } @@ -533,9 +544,9 @@ bool Download::downloadDailyData(QDate startDate, QDate endDate, QString dataset } -bool Download::downloadHourlyData(QDate startDate, QDate endDate, QString dataset, QList stations, QList variables) +bool Download::downloadHourlyData(const QDate &startDate, const QDate &endDate, const QString &dataset, + QList &stations, QList &variables, QString &errorString) { - QList variableList = _dbMeteo->getVariableProperties(variables); if (variableList.size() == 0) return false; @@ -562,7 +573,7 @@ bool Download::downloadHourlyData(QDate startDate, QDate endDate, QString datase endTime = endTime.addSecs(3600 * 24); // reftime - QString refTime = QString("reftime:>=%1,<=%2").arg(startTime.toString("yyyy-MM-dd hh:mm")).arg(endTime.toString("yyyy-MM-dd hh:mm")); + QString refTime = QString("reftime:>=%1,<=%2").arg(startTime.toString("yyyy-MM-dd hh:mm"), endTime.toString("yyyy-MM-dd hh:mm")); QEventLoop loop; @@ -587,10 +598,18 @@ bool Download::downloadHourlyData(QDate startDate, QDate endDate, QString datase countStation = countStation+1; j = j+1; } + + bool isOk; + url = QUrl(QString("%1/query").arg(_dbMeteo->getDatasetURL(dataset, isOk))); + if (! isOk) + { + errorString = _dbMeteo->getErrorString(); + return false; + } + QNetworkAccessManager* manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit())); - url = QUrl(QString("%1/query").arg(_dbMeteo->getDatasetURL(dataset))); request.setUrl(url); request.setRawHeader("Authorization", _authorization); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); @@ -604,7 +623,7 @@ bool Download::downloadHourlyData(QDate startDate, QDate endDate, QString datase if (reply->error() != QNetworkReply::NoError) { - qDebug( "Network Error" ); + errorString = "Network Error"; delete reply; delete manager; return false; diff --git a/dbMeteoPoints/download.h b/dbMeteoPoints/download.h index 1dab6823..96316a64 100644 --- a/dbMeteoPoints/download.h +++ b/dbMeteoPoints/download.h @@ -16,8 +16,12 @@ bool getPointPropertiesFromId(QString id, Crit3DMeteoPoint* pointProp); QMap getArmiketIdList(QList datasetList); void downloadMetadata(QJsonObject obj); - bool downloadDailyData(QDate startDate, QDate endDate, QString dataset, QList stations, QList variables, bool prec0024); - bool downloadHourlyData(QDate startDate, QDate endDate, QString dataset, QList stations, QList variables); + + bool downloadDailyData(const QDate &startDate, const QDate &endDate, const QString &dataset, + QList &stations, QList &variables, bool prec0024, QString &errorString); + + bool downloadHourlyData(const QDate &startDate, const QDate &endDate, const QString &dataset, + QList &stations, QList &variables, QString &errorString); DbArkimet* getDbArkimet(); diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index fcba0433..29e44e00 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -1568,7 +1568,10 @@ bool PragaProject::downloadDailyDataArkimet(QList variables, bool prec0 while (date1 <= endDate) { - myDownload->downloadDailyData(date1, date2, datasetList[i], idList[i], arkIdVar, prec0024); + if (! myDownload->downloadDailyData(date1, date2, datasetList[i], idList[i], arkIdVar, prec0024, errorString)) + { + return false; + } if (showInfo) { @@ -1617,7 +1620,7 @@ bool PragaProject::downloadHourlyDataArkimet(QList variables, QDate sta id = QString::fromStdString(meteoPoints[i].id); dataset = QString::fromStdString(meteoPoints[i].dataset); - if (!datasetList.contains(dataset)) + if (! datasetList.contains(dataset)) { datasetList << dataset; QList myList; @@ -1650,8 +1653,11 @@ bool PragaProject::downloadHourlyDataArkimet(QList variables, QDate sta updateProgressBar(startDate.daysTo(date2) + 1); } - if (! myDownload->downloadHourlyData(date1, date2, datasetList[i], idList[i], arkIdVar)) - updateProgressBarText("NO DATA"); + errorString = ""; + if (! myDownload->downloadHourlyData(date1, date2, datasetList[i], idList[i], arkIdVar, errorString)) + { + updateProgressBarText("NO DATA: " + errorString); + } date1 = date2.addDays(1); date2 = std::min(date1.addDays(MAXDAYS_DOWNLOAD_HOURLY), endDate); From e421e7d373530606b26050f1c2cd8a586c43677b Mon Sep 17 00:00:00 2001 From: giadasan Date: Tue, 25 Jun 2024 16:13:04 +0200 Subject: [PATCH 096/179] update soil table --- meteo/meteoPoint.cpp | 2 +- meteo/quality.h | 3 +- soil/soil.cpp | 1 - soil/soil.h | 1 + soil/soilDbTools.cpp | 2 +- soilWidget/soilTable.cpp | 10 +++---- soilWidget/soilWidget.cpp | 5 +++- soilWidget/tabHorizons.cpp | 59 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 72 insertions(+), 11 deletions(-) diff --git a/meteo/meteoPoint.cpp b/meteo/meteoPoint.cpp index ab3908d1..f823c063 100644 --- a/meteo/meteoPoint.cpp +++ b/meteo/meteoPoint.cpp @@ -1326,7 +1326,7 @@ bool Crit3DMeteoPoint::getDailyDataCsv_TPrec(std::string &outStr) outStr = "Date, Tmin (C), Tmax (C), Tavg (C), Prec (mm)\n"; std::ostringstream valueStream; - for (int i = 0; i < obsDataD.size(); i++) + for (int i = 0; i < int(obsDataD.size()); i++) { // Date outStr += obsDataD[i].date.toStdString() + ","; diff --git a/meteo/quality.h b/meteo/quality.h index c6de84c7..aadb5362 100644 --- a/meteo/quality.h +++ b/meteo/quality.h @@ -28,8 +28,7 @@ class Range { private: - float _max; - float _min; + float _min, _max; public: Range() { _min = NODATA; _max = NODATA; } diff --git a/soil/soil.cpp b/soil/soil.cpp index f461172d..f24f982d 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -383,7 +383,6 @@ namespace soil } } - double estimateSpecificDensity(double organicMatter) { if (int(organicMatter) == int(NODATA)) diff --git a/soil/soil.h b/soil/soil.h index 6f80b0f5..9212ceee 100644 --- a/soil/soil.h +++ b/soil/soil.h @@ -150,6 +150,7 @@ Crit3DVanGenuchten vanGenuchten; Crit3DWaterConductivity waterConductivity; Crit3DDriessen Driessen; + Crit3DGeotechnicsClass geotechnics; Crit3DHorizon(); diff --git a/soil/soilDbTools.cpp b/soil/soilDbTools.cpp index 06fd0a3a..6c731ba7 100644 --- a/soil/soilDbTools.cpp +++ b/soil/soilDbTools.cpp @@ -297,7 +297,7 @@ bool loadSoilData(const QSqlDatabase &dbSoil, const QString &soilCode, soil::Cri getValue(query.value("k_sat"), &ksat); mySoil.horizon[i].dbData.kSat = ksat; - // NEW fields for soil stability, not present in old databases + // NEW fields for slope stability, not present in old databases QList fieldList = getFields(query); double value = NODATA; diff --git a/soilWidget/soilTable.cpp b/soilWidget/soilTable.cpp index fc5ab086..d6a03647 100644 --- a/soilWidget/soilTable.cpp +++ b/soilWidget/soilTable.cpp @@ -18,16 +18,16 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) QList tableHeader; if (type == dbTable) { - this->setColumnCount(10); - tableHeader << "Upper depth [cm]" << "Lower depth [cm]" << "Sand [%]" << "Silt [%]" << "Clay [%]" << "Coarse [%]" << "O.M. [%]" - << "B.D. [g/cm3]" << "K Sat [cm/d]" << "Theta S [-]"; + this->setColumnCount(12); + tableHeader << "Upper depth [cm]" << "Lower depth [cm]" << "Sand [%]" << "Silt[%]" << "Clay [%]" << "Coarse [%]" << "O.M. [%]" + << "B.D. [g/cm3]" << "K Sat [cm/d]" << "Theta S [-]" << "c' [kPa]" << "ฮฆ' [ยฐ]"; } else if (type == modelTable) { - this->setColumnCount(11); + this->setColumnCount(13); tableHeader << "USDA Texture" << "Coarse [%]" << "O.M. [%]" << "B.D. [g/cm3]" << "K Sat [cm/d]" << "ThetaS [-]" << "ThetaR [-]" << "Air entry [KPa]" - << "alpha [KPa^-1]" << " n [-] " << " m [-] "; + << "alpha [KPa^-1]" << " n [-] " << " m [-] " << "c' [kPa]" << "ฮฆ' [ยฐ]"; } this->setHorizontalHeaderLabels(tableHeader); diff --git a/soilWidget/soilWidget.cpp b/soilWidget/soilWidget.cpp index f6af3ab0..e949dd44 100644 --- a/soilWidget/soilWidget.cpp +++ b/soilWidget/soilWidget.cpp @@ -291,7 +291,10 @@ void Crit3DSoilWidget::setDbSoil(QSqlDatabase dbOpened, QString soilCode) } // load default geotechnics parameters (not mandatory) - loadGeotechnicsParameters(dbSoil, geotechnicsClassList, errorStr); + if (! loadGeotechnicsParameters(dbSoil, geotechnicsClassList, errorStr)) + { + QMessageBox::warning(nullptr, "Warning", "loadGeotechnicsParameters: " + errorStr); + } // read soil list QList soilStringList; diff --git a/soilWidget/tabHorizons.cpp b/soilWidget/tabHorizons.cpp index 3ea30816..3162bbd6 100644 --- a/soilWidget/tabHorizons.cpp +++ b/soilWidget/tabHorizons.cpp @@ -111,6 +111,10 @@ void TabHorizons::insertSoilHorizons(soil::Crit3DSoil *soil, std::vectoritem(i,8)->setTextAlignment(Qt::AlignRight); tableDb->setItem(i, 9, new QTableWidgetItem( QString::number(mySoil->horizon[i].dbData.thetaSat, 'f', 3))); tableDb->item(i,9)->setTextAlignment(Qt::AlignRight); + tableDb->setItem(i, 10, new QTableWidgetItem( QString::number(mySoil->horizon[i].dbData.effectiveCohesion, 'f', 0))); + tableDb->item(i,10)->setTextAlignment(Qt::AlignRight); + tableDb->setItem(i, 11, new QTableWidgetItem( QString::number(mySoil->horizon[i].dbData.frictionAngle, 'f', 0))); + tableDb->item(i,11)->setTextAlignment(Qt::AlignRight); tableModel->setItem(i, 0, new QTableWidgetItem( QString::fromStdString(mySoil->horizon[i].texture.classNameUSDA))); if (mySoil->horizon[i].coarseFragments != NODATA) @@ -149,6 +153,10 @@ void TabHorizons::insertSoilHorizons(soil::Crit3DSoil *soil, std::vectoritem(i,9)->setTextAlignment(Qt::AlignRight); tableModel->setItem(i, 10, new QTableWidgetItem( QString::number(mySoil->horizon[i].vanGenuchten.m, 'f', 3 ))); tableModel->item(i,10)->setTextAlignment(Qt::AlignRight); + tableModel->setItem(i, 11, new QTableWidgetItem( QString::number(mySoil->horizon[i].effectiveCohesion, 'f', 0 ))); + tableModel->item(i,11)->setTextAlignment(Qt::AlignRight); + tableModel->setItem(i, 12, new QTableWidgetItem( QString::number(mySoil->horizon[i].frictionAngle, 'f', 0 ))); + tableModel->item(i,12)->setTextAlignment(Qt::AlignRight); } // check all Depths @@ -237,6 +245,10 @@ void TabHorizons::updateTableModel(soil::Crit3DSoil *soil) tableModel->item(i,9)->setTextAlignment(Qt::AlignRight); tableModel->setItem(i, 10, new QTableWidgetItem( QString::number(mySoil->horizon[i].vanGenuchten.m, 'f', 3 ))); tableModel->item(i,10)->setTextAlignment(Qt::AlignRight); + tableModel->setItem(i, 11, new QTableWidgetItem( QString::number(mySoil->horizon[i].effectiveCohesion, 'f', 0 ))); + tableModel->item(i,11)->setTextAlignment(Qt::AlignRight); + tableModel->setItem(i, 12, new QTableWidgetItem( QString::number(mySoil->horizon[i].frictionAngle, 'f', 0 ))); + tableModel->item(i,12)->setTextAlignment(Qt::AlignRight); } // check other values @@ -354,6 +366,17 @@ bool TabHorizons::checkHorizonData(int horizonNum) tableDb->item(horizonNum,9)->setBackground(Qt::red); } + if (dbData->effectiveCohesion != NODATA && (dbData->effectiveCohesion < 0)) + { + tableDb->item(horizonNum,10)->setBackground(Qt::red); + } + + if (dbData->frictionAngle != NODATA && (dbData->frictionAngle < 0)) + { + tableDb->item(horizonNum,11)->setBackground(Qt::red); + } + + return goOn; } @@ -372,6 +395,8 @@ void TabHorizons::setInvalidTableModelRow(int horizonNum) tableModel->item(horizonNum,8)->setBackground(Qt::red); tableModel->item(horizonNum,9)->setBackground(Qt::red); tableModel->item(horizonNum,10)->setBackground(Qt::red); + tableModel->item(horizonNum,11)->setBackground(Qt::red); + tableModel->item(horizonNum,12)->setBackground(Qt::red); } @@ -436,6 +461,7 @@ void TabHorizons::checkComputedValues(int horizonNum) { tableModel->item(horizonNum,5)->setBackground(Qt::yellow); } + } @@ -703,6 +729,34 @@ void TabHorizons::cellChanged(int row, int column) } break; } + case 10: + { + if (data == QString::number(NODATA) || data.isEmpty()) + { + mySoil->horizon[unsigned(row)].dbData.effectiveCohesion = NODATA; + tableDb->item(row, column)->setText(""); + } + else + { + mySoil->horizon[unsigned(row)].dbData.effectiveCohesion = data.toDouble(); + tableDb->item(row, column)->setText(QString::number(data.toDouble(), 'f', 0)); + } + break; + } + case 11: + { + if (data == QString::number(NODATA) || data.isEmpty()) + { + mySoil->horizon[unsigned(row)].dbData.frictionAngle = NODATA; + tableDb->item(row, column)->setText(""); + } + else + { + mySoil->horizon[unsigned(row)].dbData.frictionAngle = data.toDouble(); + tableDb->item(row, column)->setText(QString::number(data.toDouble(), 'f', 0)); + } + break; + } } std::string errorString; @@ -737,6 +791,9 @@ void TabHorizons::cellChanged(int row, int column) tableModel->item(row,8)->setText(QString::number(mySoil->horizon[unsigned(row)].vanGenuchten.alpha, 'f', 3)); tableModel->item(row,9)->setText(QString::number(mySoil->horizon[unsigned(row)].vanGenuchten.n, 'f', 3)); tableModel->item(row,10)->setText(QString::number(mySoil->horizon[unsigned(row)].vanGenuchten.m, 'f', 3)); + tableModel->item(row,11)->setText(QString::number(mySoil->horizon[unsigned(row)].effectiveCohesion, 'f', 0)); + tableModel->item(row,12)->setText(QString::number(mySoil->horizon[unsigned(row)].frictionAngle, 'f', 0)); + // reset background color for the row changed for (int j = 0; j < tableDb->columnCount(); j++) @@ -843,6 +900,8 @@ void TabHorizons::addRowClicked() newHorizon->dbData.bulkDensity = NODATA; newHorizon->dbData.thetaSat = NODATA; newHorizon->dbData.kSat = NODATA; + newHorizon->dbData.effectiveCohesion = NODATA; + newHorizon->dbData.frictionAngle = NODATA; mySoil->addHorizon(numRow, *newHorizon); // check all Depths From 84c2597d5ab6a096149fe931600e1b148b3d384e Mon Sep 17 00:00:00 2001 From: giadasan Date: Tue, 25 Jun 2024 16:36:50 +0200 Subject: [PATCH 097/179] soil table update --- soilWidget/soilTable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soilWidget/soilTable.cpp b/soilWidget/soilTable.cpp index d6a03647..5f679553 100644 --- a/soilWidget/soilTable.cpp +++ b/soilWidget/soilTable.cpp @@ -19,7 +19,7 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) if (type == dbTable) { this->setColumnCount(12); - tableHeader << "Upper depth [cm]" << "Lower depth [cm]" << "Sand [%]" << "Silt[%]" << "Clay [%]" << "Coarse [%]" << "O.M. [%]" + tableHeader << "Upper depth [cm]" << "Lower depth [cm]" << "Sand [%]" << "Silt [%]" << "Clay [%]" << "Coarse [%]" << "O.M. [%]" << "B.D. [g/cm3]" << "K Sat [cm/d]" << "Theta S [-]" << "c' [kPa]" << "ฮฆ' [ยฐ]"; } else if (type == modelTable) @@ -27,7 +27,7 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) this->setColumnCount(13); tableHeader << "USDA Texture" << "Coarse [%]" << "O.M. [%]" << "B.D. [g/cm3]" << "K Sat [cm/d]" << "ThetaS [-]" << "ThetaR [-]" << "Air entry [KPa]" - << "alpha [KPa^-1]" << " n [-] " << " m [-] " << "c' [kPa]" << "ฮฆ' [ยฐ]"; + << "ฮฑ [KPa^-1]" << " n [-] " << " m [-] " << "c' [kPa]" << "ฮฆ' [ยฐ]"; } this->setHorizontalHeaderLabels(tableHeader); From 1f553d7bd9ceb29eccb1051dd89b9db6dfec303c Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 25 Jun 2024 19:55:42 +0200 Subject: [PATCH 098/179] fix evaporation --- criteria1DWidget/tabIrrigation.cpp | 63 +++++++++++++++--------------- criteria1DWidget/tabIrrigation.h | 10 +++-- criteria1DWidget/tabLAI.cpp | 4 +- criteria1DWidget/tabLAI.h | 2 +- criteriaModel/water1D.cpp | 4 +- 5 files changed, 42 insertions(+), 41 deletions(-) diff --git a/criteria1DWidget/tabIrrigation.cpp b/criteria1DWidget/tabIrrigation.cpp index eee9775b..0e6408f3 100644 --- a/criteria1DWidget/tabIrrigation.cpp +++ b/criteria1DWidget/tabIrrigation.cpp @@ -16,14 +16,20 @@ TabIrrigation::TabIrrigation() seriesLAI = new QLineSeries(); seriesMaxTransp = new QLineSeries(); seriesRealTransp = new QLineSeries(); + seriesMaxEvap = new QLineSeries(); + seriesRealEvap = new QLineSeries(); seriesLAI->setName("LAI [m2 m-2]"); seriesMaxTransp->setName("Transpiration max [mm]"); - seriesRealTransp->setName("Transpiration real [mm]"); + seriesRealTransp->setName("actual Transpiration [mm]"); + seriesMaxEvap->setName("Evaporation max [mm]"); + seriesRealEvap->setName("actual Evaporation [mm]"); - seriesLAI->setColor(QColor(Qt::darkGreen)); + seriesLAI->setColor(QColor(Qt::green)); seriesMaxTransp->setColor(QColor(0,0,1,255)); seriesRealTransp->setColor(QColor(Qt::red)); + seriesMaxEvap->setColor(QColor(Qt::gray)); + seriesRealEvap->setColor(QColor(Qt::yellow)); seriesPrecIrr = new QBarSeries(); @@ -71,16 +77,22 @@ TabIrrigation::TabIrrigation() chart->addSeries(seriesLAI); chart->addSeries(seriesMaxTransp); chart->addSeries(seriesRealTransp); + chart->addSeries(seriesMaxEvap); + chart->addSeries(seriesRealEvap); chart->addSeries(seriesPrecIrr); seriesLAI->attachAxis(axisX); seriesMaxTransp->attachAxis(axisX); seriesRealTransp->attachAxis(axisX); + seriesMaxEvap->attachAxis(axisX); + seriesRealEvap->attachAxis(axisX); seriesPrecIrr->attachAxis(axisX); seriesLAI->attachAxis(axisY); seriesMaxTransp->attachAxis(axisY); seriesRealTransp->attachAxis(axisY); + seriesMaxEvap->attachAxis(axisY); + seriesRealEvap->attachAxis(axisY); seriesPrecIrr->attachAxis(axisYdx); chart->legend()->setVisible(true); @@ -96,8 +108,10 @@ TabIrrigation::TabIrrigation() m_tooltip->hide(); connect(seriesLAI, &QLineSeries::hovered, this, &TabIrrigation::tooltipLAI); - connect(seriesMaxTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipMT); - connect(seriesRealTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipRT); + connect(seriesMaxTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); + connect(seriesRealTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); + connect(seriesMaxEvap, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); + connect(seriesRealEvap, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); connect(seriesPrecIrr, &QHorizontalBarSeries::hovered, this, &TabIrrigation::tooltipPrecIrr); foreach(QLegendMarker* marker, chart->legend()->markers()) { @@ -139,6 +153,8 @@ void TabIrrigation::computeIrrigation(Crit1DCase &myCase, int firstYear, int las seriesLAI->clear(); seriesMaxTransp->clear(); seriesRealTransp->clear(); + seriesMaxEvap->clear(); + seriesRealEvap->clear(); categories.clear(); if (setPrec!= nullptr) @@ -184,6 +200,8 @@ void TabIrrigation::computeIrrigation(Crit1DCase &myCase, int firstYear, int las seriesLAI->append(doy, myCase.crop.LAI); seriesMaxTransp->append(doy, myCase.output.dailyMaxTranspiration); seriesRealTransp->append(doy, myCase.output.dailyTranspiration); + seriesMaxEvap->append(doy, myCase.output.dailyMaxEvaporation); + seriesRealEvap->append(doy, myCase.output.dailyEvaporation); *setPrec << myCase.output.dailyPrec; *setIrrigation << myCase.output.dailyIrrigation; } @@ -215,9 +233,9 @@ void TabIrrigation::computeIrrigation(Crit1DCase &myCase, int firstYear, int las } } -void TabIrrigation::tooltipLAI(QPointF point, bool state) +void TabIrrigation::tooltipLAI(QPointF point, bool isShow) { - if (state) + if (isShow) { QDate xDate(firstYear, 1, 1); int doy = int(round(point.x())); // start from 0 @@ -234,34 +252,15 @@ void TabIrrigation::tooltipLAI(QPointF point, bool state) } } -void TabIrrigation::tooltipMT(QPointF point, bool state) -{ - if (state) - { - QDate xDate(firstYear, 1, 1); - int doy = int(round(point.x())); - xDate = xDate.addDays(doy); - m_tooltip->setText(QString("%1 \nTransp max %2 ").arg(xDate.toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); - m_tooltip->setAnchor(point); - m_tooltip->setZValue(11); - m_tooltip->updateGeometry(); - m_tooltip->show(); - } - else - { - m_tooltip->hide(); - } - -} -void TabIrrigation::tooltipRT(QPointF point, bool state) +void TabIrrigation::tooltipEvapTransp(QPointF point, bool isShow) { - if (state) + if (isShow) { QDate xDate(firstYear, 1, 1); int doy = int(round(point.x())); xDate = xDate.addDays(doy); - m_tooltip->setText(QString("%1 \nTransp real %2 ").arg(xDate.toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + "evap/transp." + QString::number(point.y(),'f', 2)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -273,12 +272,12 @@ void TabIrrigation::tooltipRT(QPointF point, bool state) } } -void TabIrrigation::tooltipPrecIrr(bool state, int index, QBarSet *barset) -{ - if (state && barset!=nullptr && index < barset->count()) - { +void TabIrrigation::tooltipPrecIrr(bool isShow, int index, QBarSet *barset) +{ + if (isShow && barset!=nullptr && index < barset->count()) + { QPoint point = QCursor::pos(); QPoint mapPoint = chartView->mapFromGlobal(point); QPointF pointF = chart->mapToValue(mapPoint,seriesPrecIrr); diff --git a/criteria1DWidget/tabIrrigation.h b/criteria1DWidget/tabIrrigation.h index 139ecdbc..9e4ab299 100644 --- a/criteria1DWidget/tabIrrigation.h +++ b/criteria1DWidget/tabIrrigation.h @@ -15,10 +15,10 @@ TabIrrigation(); void computeIrrigation(Crit1DCase &myCase, int firstYear, int lastYear, const QDate &lastDBMeteoDate); - void tooltipLAI(QPointF point, bool state); - void tooltipMT(QPointF point, bool state); - void tooltipRT(QPointF point, bool state); - void tooltipPrecIrr(bool state, int index, QBarSet *barset); + void tooltipLAI(QPointF point, bool isShow); + void tooltipEvapTransp(QPointF point, bool isShow); + void tooltipPrecIrr(bool isShow, int index, QBarSet *barset); + void handleMarkerClicked(); private: @@ -33,6 +33,8 @@ QLineSeries* seriesLAI; QLineSeries* seriesMaxTransp; QLineSeries* seriesRealTransp; + QLineSeries* seriesMaxEvap; + QLineSeries* seriesRealEvap; QBarSeries* seriesPrecIrr; QBarSet *setPrec; QBarSet *setIrrigation; diff --git a/criteria1DWidget/tabLAI.cpp b/criteria1DWidget/tabLAI.cpp index 4f033b3f..292dec8e 100644 --- a/criteria1DWidget/tabLAI.cpp +++ b/criteria1DWidget/tabLAI.cpp @@ -89,7 +89,7 @@ TabLAI::TabLAI() connect(seriesLAI, &QLineSeries::hovered, this, &TabLAI::tooltipLAI); connect(seriesPotentialEvap, &QLineSeries::hovered, this, &TabLAI::tooltipPE); connect(seriesMaxEvap, &QLineSeries::hovered, this, &TabLAI::tooltipME); - connect(seriesMaxTransp, &QLineSeries::hovered, this, &TabLAI::tooltipMT); + connect(seriesMaxTransp, &QLineSeries::hovered, this, &TabLAI::tooltipMaxTranspiration); foreach(QLegendMarker* marker, chart->legend()->markers()) { @@ -239,7 +239,7 @@ void TabLAI::tooltipME(QPointF point, bool state) } } -void TabLAI::tooltipMT(QPointF point, bool state) +void TabLAI::tooltipMaxTranspiration(QPointF point, bool state) { if (state) diff --git a/criteria1DWidget/tabLAI.h b/criteria1DWidget/tabLAI.h index 219a3264..76846788 100644 --- a/criteria1DWidget/tabLAI.h +++ b/criteria1DWidget/tabLAI.h @@ -20,7 +20,7 @@ void tooltipLAI(QPointF point, bool state); void tooltipPE(QPointF point, bool state); void tooltipME(QPointF point, bool state); - void tooltipMT(QPointF point, bool state); + void tooltipMaxTranspiration(QPointF point, bool state); void handleMarkerClicked(); private: QChartView *chartView; diff --git a/criteriaModel/water1D.cpp b/criteriaModel/water1D.cpp index ad12d796..e6d20bc7 100644 --- a/criteriaModel/water1D.cpp +++ b/criteriaModel/water1D.cpp @@ -417,13 +417,13 @@ double computeEvaporation(std::vector &soilLayers, double max bool isWaterSupply = true; double sumEvap, evapLayerThreshold, evapLayer; int nrIteration = 0; - while ((residualEvaporation > EPSILON) && (isWaterSupply == true) && nrIteration < 5) + while ((residualEvaporation > EPSILON) && (isWaterSupply == true) && nrIteration < 3) { sumEvap = 0.0; for (int i=1; i <= nrEvapLayers; i++) { - evapLayer = residualEvaporation * (coeffEvap[i-1] / sumCoeff); + evapLayer = residualEvaporation * coeffEvap[i-1]; evapLayerThreshold = soilLayers[i].HH + (soilLayers[i].FC - soilLayers[i].HH) * coeffThreshold[i-1]; if (soilLayers[i].waterContent > (evapLayerThreshold + evapLayer)) From 6e10ea3e6912d66ed47c96f94e680c8a4f12988f Mon Sep 17 00:00:00 2001 From: giadasan Date: Wed, 26 Jun 2024 13:28:50 +0200 Subject: [PATCH 099/179] fix mingw issues & update soil model table --- crop/landUnit.cpp | 2 +- gis/gis.cpp | 14 +++++++------- gis/gisIO.cpp | 2 +- mathFunctions/furtherMathFunctions.cpp | 20 ++++++++++---------- soilWidget/tabHorizons.cpp | 10 ++++++++++ utilities/utilities.cpp | 4 ++-- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/crop/landUnit.cpp b/crop/landUnit.cpp index 15baddc8..be279418 100644 --- a/crop/landUnit.cpp +++ b/crop/landUnit.cpp @@ -63,7 +63,7 @@ bool loadLandUnitList(const QSqlDatabase &dbCrop, std::vector &l int getLandUnitIndex(const std::vector &landUnitList, int idLandUnit) { - for (int index = 0; index < landUnitList.size(); index++) + for (int index = 0; index < int(landUnitList.size()); index++) if (landUnitList[index].id == idLandUnit) return index; diff --git a/gis/gis.cpp b/gis/gis.cpp index 7a0a1fbd..ab29e104 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -290,7 +290,7 @@ namespace gis if (!parametersCell.empty()) parametersCell.clear(); parametersCell.resize(initHeader.nrRows*initHeader.nrCols); - for (int i = 0; i < parametersCell.size(); i++) + for (int i = 0; i < int(parametersCell.size()); i++) { parametersCell[i].row = i / initHeader.nrCols; parametersCell[i].col = i % initHeader.nrCols; @@ -303,7 +303,7 @@ namespace gis bool Crit3DRasterGrid::initializeParametersLatLonHeader(const Crit3DLatLonHeader& latLonHeader) { parametersCell.resize(latLonHeader.nrRows*latLonHeader.nrCols); - for (int i = 0; i < parametersCell.size(); i++) + for (int i = 0; i < int(parametersCell.size()); i++) { parametersCell[i].row = i / latLonHeader.nrCols; parametersCell[i].col = i % latLonHeader.nrCols; @@ -498,7 +498,7 @@ namespace gis int index = row * header->nrCols + col; - if (index < parametersCell.size()) + if (index < int(parametersCell.size())) parameters = parametersCell[index].fittingParameters; return parameters; @@ -538,16 +538,16 @@ namespace gis for (j = col-1; j < col+2; j++) { index = i * header->nrCols + j; - if (index >= 0 && index < parametersCell.size() && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) + if (index >= 0 && index < int(parametersCell.size()) && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) findFirst = 1; if (findFirst==1) break; } if (findFirst==1) break; } - for (k = 0; k < parametersCell[index].fittingParameters.size(); k++) + for (k = 0; k < int(parametersCell[index].fittingParameters.size()); k++) { - for (l = 0; l < parametersCell[index].fittingParameters[k].size(); l++) + for (l = 0; l < int(parametersCell[index].fittingParameters[k].size()); l++) { avg = 0; counter = 0; @@ -556,7 +556,7 @@ namespace gis for (int m = j; m < col+2; m++) { index = h * header->nrCols + m; - if (index >= 0 && index < parametersCell.size() && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) + if (index >= 0 && index < int(parametersCell.size()) && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) { avg += parametersCell[index].fittingParameters[k][l]; counter++; diff --git a/gis/gisIO.cpp b/gis/gisIO.cpp index f81fcbeb..d09fda69 100644 --- a/gis/gisIO.cpp +++ b/gis/gisIO.cpp @@ -237,7 +237,7 @@ namespace gis // remove the curly braces, split the values โ€‹โ€‹and remove the spaces cleanBraces(valueStr); vector infoStr = splitCommaDelimited(valueStr); - for (int i = 0; i < infoStr.size(); i++) + for (int i = 0; i < int(infoStr.size()); i++) { cleanSpaces(infoStr[i]); } diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 202b49b7..e43306ea 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -218,7 +218,7 @@ double multilinear(std::vector &x, std::vector &par) return NODATA; double y = 0; - for (int i=0; i < x.size(); i++) + for (int i=0; i < int(x.size()); i++) y += par[i] * x[i]; y += par[x.size()]; @@ -1136,13 +1136,13 @@ namespace interpolation double meanObs=0; double RSS=0; double TSS=0; - for (int i=0;i (nrPredictors+1)) + if (int(observed.size()) > (nrPredictors+1)) standardError = sqrt(sum_weighted_squared_residuals/(observed.size()-nrPredictors-1)); else standardError = sqrt(sum_weighted_squared_residuals/(observed.size()-1)); @@ -1943,7 +1943,7 @@ namespace interpolation double error; double norm = 0; - for (int i = 0; i < y.size(); i++) + for (int i = 0; i < int(y.size()); i++) { error = y[i] - func(myFunc,x[i], parameters); norm += error * error * weights[i] * weights[i]; @@ -2009,7 +2009,7 @@ namespace interpolation { for (int dir = 0; dir < 2; ++dir) { - for (int paramIndex = 0; paramIndex < numParamsToVary; ++paramIndex) + for (int paramIndex = 0; paramIndex < int(numParamsToVary); ++paramIndex) { fittingMarquardt_nDimension_noSquares_singleFunction(func,parametersMin, diff --git a/soilWidget/tabHorizons.cpp b/soilWidget/tabHorizons.cpp index 3162bbd6..51e1430a 100644 --- a/soilWidget/tabHorizons.cpp +++ b/soilWidget/tabHorizons.cpp @@ -462,6 +462,16 @@ void TabHorizons::checkComputedValues(int horizonNum) tableModel->item(horizonNum,5)->setBackground(Qt::yellow); } + if (horizon->dbData.effectiveCohesion == NODATA) + { + tableModel->item(horizonNum,11)->setBackground(Qt::yellow); + } + + if (horizon->dbData.frictionAngle == NODATA) + { + tableModel->item(horizonNum,12)->setBackground(Qt::yellow); + } + } diff --git a/utilities/utilities.cpp b/utilities/utilities.cpp index 426322af..ea945b74 100644 --- a/utilities/utilities.cpp +++ b/utilities/utilities.cpp @@ -672,12 +672,12 @@ bool writeJson(const QString & ancestor, const std::vector &fieldNames bool isFloat = false; - for (int i=0; i < values.size(); i++) + for (int i=0; i < int(values.size()); i++) { if (values[i].size() != fieldNames.size() || values[i].size() != dataType.size()) return false; recordObject.empty(); - for (int j=0; j < values[i].size(); j++) + for (int j=0; j < int(values[i].size()); j++) { if (dataType[j] == "float") recordObject.insert(fieldNames[j], values[i][j].toFloat(&isFloat)); From f47d6969bb3e9a07e1120462e0ee4b96f550fe38 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 26 Jun 2024 17:29:29 +0200 Subject: [PATCH 100/179] add tooltip --- criteria1DWidget/tabIrrigation.cpp | 3 ++- criteriaModel/criteria1DMeteo.cpp | 19 +++++++++++++++---- soilWidget/soilTable.cpp | 19 +++++++++++++++++-- soilWidget/soilWidget.cpp | 6 +++--- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/criteria1DWidget/tabIrrigation.cpp b/criteria1DWidget/tabIrrigation.cpp index 0e6408f3..79fa8066 100644 --- a/criteria1DWidget/tabIrrigation.cpp +++ b/criteria1DWidget/tabIrrigation.cpp @@ -253,6 +253,7 @@ void TabIrrigation::tooltipLAI(QPointF point, bool isShow) } +// TODO Giada void TabIrrigation::tooltipEvapTransp(QPointF point, bool isShow) { if (isShow) @@ -260,7 +261,7 @@ void TabIrrigation::tooltipEvapTransp(QPointF point, bool isShow) QDate xDate(firstYear, 1, 1); int doy = int(round(point.x())); xDate = xDate.addDays(doy); - m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + "evap/transp." + QString::number(point.y(),'f', 2)); + m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + "evap/transp. " + QString::number(point.y(),'f', 2)+ "mm"); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); diff --git a/criteriaModel/criteria1DMeteo.cpp b/criteriaModel/criteria1DMeteo.cpp index f79b3b03..449c2859 100644 --- a/criteriaModel/criteria1DMeteo.cpp +++ b/criteriaModel/criteria1DMeteo.cpp @@ -714,8 +714,6 @@ bool fillDailyTempPrecCriteria1D(QSqlDatabase* dbMeteo, QString table, Crit3DMet } QDate date; - QDate previousDate(validYear-1, 12, 31); - QDate lastDate(validYear, 12, 31); float tmin = NODATA; float tmax = NODATA; float tavg = NODATA; @@ -728,6 +726,9 @@ bool fillDailyTempPrecCriteria1D(QSqlDatabase* dbMeteo, QString table, Crit3DMet const float tmax_min = -40; const float tmax_max = 60; + QList fieldList = getFieldsUpperCase(query); + bool existWatertable = fieldList.contains("WATERTABLE"); + do { getValue(query.value("date"), &date); @@ -736,8 +737,18 @@ bool fillDailyTempPrecCriteria1D(QSqlDatabase* dbMeteo, QString table, Crit3DMet getValue(query.value("prec"), &prec); // Watertable depth [m] - getValue(query.value("watertable"), &waterTable); - if (waterTable < 0.f) waterTable = NODATA; + if (existWatertable) + { + getValue(query.value("watertable"), &waterTable); + if (waterTable < 0.f) + { + waterTable = NODATA; + } + } + else + { + waterTable = NODATA; + } if (tmin < tmin_min || tmin > tmin_max) { diff --git a/soilWidget/soilTable.cpp b/soilWidget/soilTable.cpp index 5f679553..6b5c32c7 100644 --- a/soilWidget/soilTable.cpp +++ b/soilWidget/soilTable.cpp @@ -34,7 +34,6 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) this->resizeColumnsToContents(); this->setSelectionMode(QAbstractItemView::SingleSelection); this->setShowGrid(true); - //this->setStyleSheet("QTableView {selection-background-color: green;}"); this->setStyleSheet("QTableView::item:selected { color:black; border: 3px solid black}"); if (type == dbTable) @@ -45,6 +44,21 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) { this->setEditTriggers(QAbstractItemView::NoEditTriggers); } + + if (type == dbTable) + { + QTableWidgetItem *currentHeaderItem = this->horizontalHeaderItem(2); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of sand (from 2.0 to 0.05 mm)"); + + //currentHeaderItem = this->horizontalHeaderItem(3); + //.. + // TODO + } + else if (type == modelTable) + { + // TODO + } } @@ -52,7 +66,8 @@ void Crit3DSoilTable::mouseMoveEvent(QMouseEvent *event) { QPoint pos = event->pos(); QTableWidgetItem *item = this->itemAt(pos); - if(!item) return; + if(! item) + return; if (item->background().color() == Qt::red) { diff --git a/soilWidget/soilWidget.cpp b/soilWidget/soilWidget.cpp index e949dd44..6db0ea06 100644 --- a/soilWidget/soilWidget.cpp +++ b/soilWidget/soilWidget.cpp @@ -55,7 +55,7 @@ Crit3DSoilWidget::Crit3DSoilWidget() geotechnicsClassList.resize(19); this->setWindowTitle(QStringLiteral("CRITERIA - Soil Editor")); - this->resize(1240, 700); + this->resize(1400, 700); // layout QVBoxLayout *mainLayout = new QVBoxLayout(); @@ -286,14 +286,14 @@ void Crit3DSoilWidget::setDbSoil(QSqlDatabase dbOpened, QString soilCode) // load default VG parameters if (! loadVanGenuchtenParameters(dbSoil, textureClassList, errorStr)) { - QMessageBox::critical(nullptr, "Error", "loadVanGenuchtenParameters: " + errorStr); + QMessageBox::critical(nullptr, "Error", "loadVanGenuchtenParameters\n" + errorStr); return; } // load default geotechnics parameters (not mandatory) if (! loadGeotechnicsParameters(dbSoil, geotechnicsClassList, errorStr)) { - QMessageBox::warning(nullptr, "Warning", "loadGeotechnicsParameters: " + errorStr); + QMessageBox::warning(nullptr, "Warning", "loadGeotechnicsParameters\n" + errorStr); } // read soil list From 8ce8a9b17398c38534ee1dbc1ef1faef87209d13 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 26 Jun 2024 19:08:20 +0200 Subject: [PATCH 101/179] fix meteowidget test --- dbMeteoPoints/dbMeteoPointsHandler.cpp | 7 +++++-- meteoWidget/meteoWidget.cpp | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dbMeteoPoints/dbMeteoPointsHandler.cpp b/dbMeteoPoints/dbMeteoPointsHandler.cpp index de82441f..2c5dfc0d 100644 --- a/dbMeteoPoints/dbMeteoPointsHandler.cpp +++ b/dbMeteoPoints/dbMeteoPointsHandler.cpp @@ -166,6 +166,7 @@ QList Crit3DMeteoPointsDbHandler::getAllDatasetsList() return datasetList; } + QDateTime Crit3DMeteoPointsDbHandler::getFirstDate(frequencyType frequency) { QSqlQuery qry(_db); @@ -183,9 +184,10 @@ QDateTime Crit3DMeteoPointsDbHandler::getFirstDate(frequencyType frequency) qry.prepare( "SELECT name FROM sqlite_master WHERE type='table' AND name like :dayHour ESCAPE '^'"); qry.bindValue(":dayHour", "%^" + dayHour + "%"); - if( !qry.exec() ) + if(! qry.exec() ) { errorStr = qry.lastError().text(); + return firstDate; } else { @@ -246,9 +248,11 @@ QDateTime Crit3DMeteoPointsDbHandler::getLastDate(frequencyType frequency) qry.prepare( "SELECT name FROM sqlite_master WHERE type='table' AND name like :dayHour ESCAPE '^'"); qry.bindValue(":dayHour", "%^_" + dayHour + "%"); + QDateTime lastDate; if(! qry.exec() ) { errorStr = qry.lastError().text(); + return lastDate; } else { @@ -259,7 +263,6 @@ QDateTime Crit3DMeteoPointsDbHandler::getLastDate(frequencyType frequency) } } - QDateTime lastDate; QDateTime currentLastDate; QDate myDate; QTime myTime; diff --git a/meteoWidget/meteoWidget.cpp b/meteoWidget/meteoWidget.cpp index e45b2b39..079031f4 100644 --- a/meteoWidget/meteoWidget.cpp +++ b/meteoWidget/meteoWidget.cpp @@ -499,9 +499,11 @@ void Crit3DMeteoWidget::updateTimeRange() lastMonthlyDate = myMonthlyDateLast; } } + checkExistingData(); } + void Crit3DMeteoWidget::checkExistingData() { // set enable/disable buttons if daily/hourly/monthly data are available From e99e85dffeaae30255190ab834bbb13cb27c6b4b Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 27 Jun 2024 18:40:31 +0200 Subject: [PATCH 102/179] vine 3D test --- gis/gis.cpp | 6 ++++++ gis/gis.h | 1 + grapevine/grapevine.h | 2 +- soil/soil.cpp | 15 ++++++++++++--- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index ab29e104..81248a10 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -771,6 +771,12 @@ namespace gis *myY = myHeader.llCorner.y + myHeader.cellSize * (myHeader.nrRows - row - 0.5); } + void getUtmXYFromRowCol(Crit3DRasterHeader *myHeader, int row, int col, double* myX, double* myY) + { + *myX = myHeader->llCorner.x + myHeader->cellSize * (col + 0.5); + *myY = myHeader->llCorner.y + myHeader->cellSize * (myHeader->nrRows - row - 0.5); + } + void getLatLonFromRowCol(const Crit3DLatLonHeader& latLonHeader, int row, int col, double* lat, double* lon) { *lon = latLonHeader.llCorner.longitude + latLonHeader.dx * (col + 0.5); diff --git a/gis/gis.h b/gis/gis.h index 9692ee6b..221e693d 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -224,6 +224,7 @@ void getUtmXYFromRowColSinglePrecision(const Crit3DRasterGrid& rasterGrid, int myRow, int myCol,float* myX,float* myY); void getUtmXYFromRowColSinglePrecision(const Crit3DRasterHeader& myHeader, int myRow, int myCol,float* myX,float* myY); void getUtmXYFromRowCol(const Crit3DRasterHeader& myHeader,int myRow, int myCol, double* myX, double* myY); + void getUtmXYFromRowCol(Crit3DRasterHeader *myHeader, int row, int col, double* myX, double* myY); void getLatLonFromRowCol(const Crit3DLatLonHeader &latLonHeader, int myRow, int myCol, double* lat, double* lon); void getLatLonFromRowCol(const Crit3DLatLonHeader &latLonHeader, const Crit3DRasterCell& v, Crit3DGeoPoint* p); diff --git a/grapevine/grapevine.h b/grapevine/grapevine.h index 7f773da6..12a4eb76 100644 --- a/grapevine/grapevine.h +++ b/grapevine/grapevine.h @@ -192,7 +192,7 @@ struct Crit3DModelCase { int id; Crit3DLanduse landuse; - int soilIndex; + //int soilIndex; float shootsPerPlant; float plantDensity; diff --git a/soil/soil.cpp b/soil/soil.cpp index 397ec2a9..880c07f0 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -353,7 +353,14 @@ namespace soil else { // FINE grained soils - if (horizon.texture.classNameUSDA == "loam" || horizon.texture.classNameUSDA == "clayloam" || horizon.texture.classNameUSDA == "silty clayloam") + if (horizon.texture.classNameUSDA == "loam") + { + if (horizon.organicMatter > 0.2) + return 16; // OL + else + return 12; // SC-CL + } + if (horizon.texture.classNameUSDA == "clayloam" || horizon.texture.classNameUSDA == "silty clayloam") { if (horizon.organicMatter > 0.2) return 16; // OL @@ -379,7 +386,7 @@ namespace soil if (horizon.organicMatter > 0.2) return 16; // OL else - return 14; // CL + return 13; // ML } } @@ -926,8 +933,10 @@ namespace soil horizon.CEC = 50.0; horizon.PH = 7.7; - // new parameters for slope stability + // USCS: Unified Soil Classification System horizon.texture.classUSCS = getUSCSClass(horizon); + + // parameters for slope stability if (horizon.dbData.effectiveCohesion != NODATA) { horizon.effectiveCohesion = horizon.dbData.effectiveCohesion; From b5f89f36a052b086e5a71c9846f1024410095e73 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 28 Jun 2024 17:39:11 +0200 Subject: [PATCH 103/179] update GUI --- criteria1DWidget/tabIrrigation.cpp | 63 +++++++++++++++--------------- criteria1DWidget/tabIrrigation.h | 4 +- criteria1DWidget/tabLAI.cpp | 60 +++++++++++++++------------- criteria1DWidget/tabLAI.h | 2 +- 4 files changed, 67 insertions(+), 62 deletions(-) diff --git a/criteria1DWidget/tabIrrigation.cpp b/criteria1DWidget/tabIrrigation.cpp index 79fa8066..d28a46c8 100644 --- a/criteria1DWidget/tabIrrigation.cpp +++ b/criteria1DWidget/tabIrrigation.cpp @@ -15,30 +15,31 @@ TabIrrigation::TabIrrigation() seriesLAI = new QLineSeries(); seriesMaxTransp = new QLineSeries(); - seriesRealTransp = new QLineSeries(); + seriesActualTransp = new QLineSeries(); seriesMaxEvap = new QLineSeries(); - seriesRealEvap = new QLineSeries(); - - seriesLAI->setName("LAI [m2 m-2]"); - seriesMaxTransp->setName("Transpiration max [mm]"); - seriesRealTransp->setName("actual Transpiration [mm]"); - seriesMaxEvap->setName("Evaporation max [mm]"); - seriesRealEvap->setName("actual Evaporation [mm]"); - - seriesLAI->setColor(QColor(Qt::green)); - seriesMaxTransp->setColor(QColor(0,0,1,255)); - seriesRealTransp->setColor(QColor(Qt::red)); + seriesActualEvap = new QLineSeries(); + + seriesLAI->setName("LAI [m2 m-2] "); + seriesMaxTransp->setName("max. Transpiration [mm]"); + seriesActualTransp->setName("actual Transpiration [mm]"); + seriesMaxEvap->setName("max. Evaporation [mm]"); + seriesActualEvap->setName("actual Evaporation [mm]"); + + QPen pen; + pen.setWidth(2); + pen.setColor(QColor(0, 200, 0, 255)); + seriesLAI->setPen(pen); + + // bug with black + seriesMaxTransp->setColor(QColor(0, 0, 1, 255)); + seriesActualTransp->setColor(QColor(Qt::red)); seriesMaxEvap->setColor(QColor(Qt::gray)); - seriesRealEvap->setColor(QColor(Qt::yellow)); + seriesActualEvap->setColor(QColor(210, 150, 20, 255)); seriesPrecIrr = new QBarSeries(); setPrec = new QBarSet("Precipitation [mm]"); setIrrigation = new QBarSet("Irrigation [mm]"); - setPrec->setColor(QColor(Qt::blue)); - setPrec->setBorderColor(QColor(Qt::blue)); - setIrrigation->setColor(QColor(Qt::cyan)); - setIrrigation->setBorderColor(QColor(Qt::cyan)); seriesPrecIrr->append(setPrec); seriesPrecIrr->append(setIrrigation); @@ -76,23 +77,23 @@ TabIrrigation::TabIrrigation() chart->addSeries(seriesLAI); chart->addSeries(seriesMaxTransp); - chart->addSeries(seriesRealTransp); + chart->addSeries(seriesActualTransp); chart->addSeries(seriesMaxEvap); - chart->addSeries(seriesRealEvap); + chart->addSeries(seriesActualEvap); chart->addSeries(seriesPrecIrr); seriesLAI->attachAxis(axisX); seriesMaxTransp->attachAxis(axisX); - seriesRealTransp->attachAxis(axisX); + seriesActualTransp->attachAxis(axisX); seriesMaxEvap->attachAxis(axisX); - seriesRealEvap->attachAxis(axisX); + seriesActualEvap->attachAxis(axisX); seriesPrecIrr->attachAxis(axisX); seriesLAI->attachAxis(axisY); seriesMaxTransp->attachAxis(axisY); - seriesRealTransp->attachAxis(axisY); + seriesActualTransp->attachAxis(axisY); seriesMaxEvap->attachAxis(axisY); - seriesRealEvap->attachAxis(axisY); + seriesActualEvap->attachAxis(axisY); seriesPrecIrr->attachAxis(axisYdx); chart->legend()->setVisible(true); @@ -109,9 +110,9 @@ TabIrrigation::TabIrrigation() connect(seriesLAI, &QLineSeries::hovered, this, &TabIrrigation::tooltipLAI); connect(seriesMaxTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); - connect(seriesRealTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); + connect(seriesActualTransp, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); connect(seriesMaxEvap, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); - connect(seriesRealEvap, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); + connect(seriesActualEvap, &QLineSeries::hovered, this, &TabIrrigation::tooltipEvapTransp); connect(seriesPrecIrr, &QHorizontalBarSeries::hovered, this, &TabIrrigation::tooltipPrecIrr); foreach(QLegendMarker* marker, chart->legend()->markers()) { @@ -152,9 +153,9 @@ void TabIrrigation::computeIrrigation(Crit1DCase &myCase, int firstYear, int las axisX->clear(); seriesLAI->clear(); seriesMaxTransp->clear(); - seriesRealTransp->clear(); + seriesActualTransp->clear(); seriesMaxEvap->clear(); - seriesRealEvap->clear(); + seriesActualEvap->clear(); categories.clear(); if (setPrec!= nullptr) @@ -168,8 +169,8 @@ void TabIrrigation::computeIrrigation(Crit1DCase &myCase, int firstYear, int las { seriesPrecIrr->remove(setIrrigation); setIrrigation = new QBarSet("Irrigation [mm]"); - setIrrigation->setColor(QColor(Qt::cyan)); - setIrrigation->setBorderColor(QColor(Qt::cyan)); + setIrrigation->setColor(QColor(16,183,235,255)); + setIrrigation->setBorderColor(QColor(16,183,235,255)); } int currentDoy = 1; @@ -199,9 +200,9 @@ void TabIrrigation::computeIrrigation(Crit1DCase &myCase, int firstYear, int las categories.append(QString::number(doy)); seriesLAI->append(doy, myCase.crop.LAI); seriesMaxTransp->append(doy, myCase.output.dailyMaxTranspiration); - seriesRealTransp->append(doy, myCase.output.dailyTranspiration); + seriesActualTransp->append(doy, myCase.output.dailyTranspiration); seriesMaxEvap->append(doy, myCase.output.dailyMaxEvaporation); - seriesRealEvap->append(doy, myCase.output.dailyEvaporation); + seriesActualEvap->append(doy, myCase.output.dailyEvaporation); *setPrec << myCase.output.dailyPrec; *setIrrigation << myCase.output.dailyIrrigation; } diff --git a/criteria1DWidget/tabIrrigation.h b/criteria1DWidget/tabIrrigation.h index 9e4ab299..2d5aedc7 100644 --- a/criteria1DWidget/tabIrrigation.h +++ b/criteria1DWidget/tabIrrigation.h @@ -32,9 +32,9 @@ QList categories; QLineSeries* seriesLAI; QLineSeries* seriesMaxTransp; - QLineSeries* seriesRealTransp; + QLineSeries* seriesActualTransp; QLineSeries* seriesMaxEvap; - QLineSeries* seriesRealEvap; + QLineSeries* seriesActualEvap; QBarSeries* seriesPrecIrr; QBarSet *setPrec; QBarSet *setIrrigation; diff --git a/criteria1DWidget/tabLAI.cpp b/criteria1DWidget/tabLAI.cpp index 292dec8e..f88eba87 100644 --- a/criteria1DWidget/tabLAI.cpp +++ b/criteria1DWidget/tabLAI.cpp @@ -18,25 +18,34 @@ TabLAI::TabLAI() chartView->setChart(chart); seriesLAI = new QLineSeries(); - seriesPotentialEvap = new QLineSeries(); - seriesMaxEvap = new QLineSeries(); + seriesLAI->setName("Leaf Area Index [m2 m-2] "); + QPen pen; + pen.setWidth(2); + seriesLAI->setPen(pen); + seriesLAI->setColor(QColor(0, 200, 0, 255)); + + seriesETP = new QLineSeries(); + seriesETP->setName("Potential evapotranspiration [mm] "); + // bug with black + seriesETP->setColor(QColor(0, 0, 1, 255)); + seriesMaxTransp = new QLineSeries(); - seriesLAI->setName("Leaf Area Index [m2 m-2]"); - seriesPotentialEvap->setName("Potential evapotranspiration [mm]"); - seriesPotentialEvap->setColor(QColor(Qt::darkGray)); - seriesMaxEvap->setName("Evaporation max [mm]"); - seriesMaxEvap->setColor(QColor(Qt::blue)); - seriesMaxTransp->setName("Transpiration max [mm]"); + seriesMaxTransp->setName("Maximum transpiration [mm] "); seriesMaxTransp->setColor(QColor(Qt::red)); + seriesMaxEvap = new QLineSeries(); + seriesMaxEvap->setName("Maximum evaporation [mm] "); + seriesMaxEvap->setColor(QColor(Qt::blue)); + axisX = new QDateTimeAxis(); axisY = new QValueAxis(); axisYdx = new QValueAxis(); chart->addSeries(seriesLAI); - chart->addSeries(seriesPotentialEvap); - chart->addSeries(seriesMaxEvap); + chart->addSeries(seriesETP); chart->addSeries(seriesMaxTransp); + chart->addSeries(seriesMaxEvap); + QDate first(QDate::currentDate().year(), 1, 1); QDate last(QDate::currentDate().year(), 12, 31); axisX->setTitleText("Date"); @@ -46,32 +55,27 @@ TabLAI::TabLAI() axisX->setTickCount(13); chart->addAxis(axisX, Qt::AlignBottom); seriesLAI->attachAxis(axisX); - seriesPotentialEvap->attachAxis(axisX); + seriesETP->attachAxis(axisX); seriesMaxEvap->attachAxis(axisX); seriesMaxTransp->attachAxis(axisX); QFont font = axisX->titleFont(); + qreal maximum = 8; axisY->setTitleText("Leaf Area Index [m2 m-2]"); axisY->setTitleFont(font); - axisY->setRange(0,7); - axisY->setTickCount(8); - - QPen pen; - pen.setWidth(3); - pen.setBrush(Qt::green); + axisY->setRange(0, maximum); + axisY->setTickCount(maximum+1); axisYdx->setTitleText("Evapotranspiration [mm]"); - axisYdx->setRange(0,7); - axisYdx->setTickCount(8); axisYdx->setTitleFont(font); - - seriesLAI->setPen(pen); + axisYdx->setRange(0, maximum); + axisYdx->setTickCount(maximum+1); chart->addAxis(axisY, Qt::AlignLeft); chart->addAxis(axisYdx, Qt::AlignRight); seriesLAI->attachAxis(axisY); - seriesPotentialEvap->attachAxis(axisYdx); + seriesETP->attachAxis(axisYdx); seriesMaxEvap->attachAxis(axisYdx); seriesMaxTransp->attachAxis(axisYdx); @@ -87,7 +91,7 @@ TabLAI::TabLAI() m_tooltip->hide(); connect(seriesLAI, &QLineSeries::hovered, this, &TabLAI::tooltipLAI); - connect(seriesPotentialEvap, &QLineSeries::hovered, this, &TabLAI::tooltipPE); + connect(seriesETP, &QLineSeries::hovered, this, &TabLAI::tooltipPE); connect(seriesMaxEvap, &QLineSeries::hovered, this, &TabLAI::tooltipME); connect(seriesMaxTransp, &QLineSeries::hovered, this, &TabLAI::tooltipMaxTranspiration); @@ -129,12 +133,12 @@ void TabLAI::computeLAI(Crit3DCrop* myCrop, Crit3DMeteoPoint *meteoPoint, int fi std::string errorStr; chart->removeSeries(seriesLAI); - chart->removeSeries(seriesPotentialEvap); + chart->removeSeries(seriesETP); chart->removeSeries(seriesMaxEvap); chart->removeSeries(seriesMaxTransp); seriesLAI->clear(); - seriesPotentialEvap->clear(); + seriesETP->clear(); seriesMaxEvap->clear(); seriesMaxTransp->clear(); @@ -161,7 +165,7 @@ void TabLAI::computeLAI(Crit3DCrop* myCrop, Crit3DMeteoPoint *meteoPoint, int fi // ET0 dailyEt0 = ET0_Hargreaves(TRANSMISSIVITY_SAMANI_COEFF_DEFAULT, meteoPoint->latitude, doy, tmax, tmin); - seriesPotentialEvap->append(x.toMSecsSinceEpoch(), dailyEt0); + seriesETP->append(x.toMSecsSinceEpoch(), dailyEt0); seriesMaxEvap->append(x.toMSecsSinceEpoch(), myCrop->getMaxEvaporation(dailyEt0)); seriesMaxTransp->append(x.toMSecsSinceEpoch(), myCrop->getMaxTranspiration(dailyEt0)); seriesLAI->append(x.toMSecsSinceEpoch(), myCrop->LAI); @@ -175,12 +179,12 @@ void TabLAI::computeLAI(Crit3DCrop* myCrop, Crit3DMeteoPoint *meteoPoint, int fi axisX->setMax(QDateTime(last, QTime(0,0,0))); chart->addSeries(seriesLAI); - chart->addSeries(seriesPotentialEvap); + chart->addSeries(seriesETP); chart->addSeries(seriesMaxEvap); chart->addSeries(seriesMaxTransp); seriesLAI->attachAxis(axisY); - seriesPotentialEvap->attachAxis(axisYdx); + seriesETP->attachAxis(axisYdx); seriesMaxEvap->attachAxis(axisYdx); seriesMaxTransp->attachAxis(axisYdx); diff --git a/criteria1DWidget/tabLAI.h b/criteria1DWidget/tabLAI.h index 76846788..af360bc3 100644 --- a/criteria1DWidget/tabLAI.h +++ b/criteria1DWidget/tabLAI.h @@ -26,7 +26,7 @@ QChartView *chartView; QChart *chart; QLineSeries *seriesLAI; - QLineSeries *seriesPotentialEvap; + QLineSeries *seriesETP; QLineSeries *seriesMaxEvap; QLineSeries *seriesMaxTransp; QDateTimeAxis *axisX; From 721e08213efbae44eab74bfc45d095d794daa90c Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 28 Jun 2024 19:53:30 +0200 Subject: [PATCH 104/179] update 3D test --- soilFluxes3D/soilFluxes3D.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soilFluxes3D/soilFluxes3D.cpp b/soilFluxes3D/soilFluxes3D.cpp index ba552106..536337c0 100644 --- a/soilFluxes3D/soilFluxes3D.cpp +++ b/soilFluxes3D/soilFluxes3D.cpp @@ -198,6 +198,7 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, } else { + // default myParameters.k_lateral_vertical_ratio = 10.; return PARAMETER_ERROR; } From ada24a49f8ba1c0bca15ef2d3508cc1d8e805818 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 1 Jul 2024 19:50:49 +0200 Subject: [PATCH 105/179] add minimum factor of safety --- gis/gis.cpp | 15 ++++++++------- meteo/meteo.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index 81248a10..f73f6405 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -1337,20 +1337,21 @@ namespace gis { float value = rasterRef.getValueFromRowCol(row,col); float aspect = aspectMap.getValueFromRowCol(row,col); - if ( isEqual(value, rasterRef.header->flag) - || isEqual(aspect, aspectMap.header->flag) ) - return false; + if (isEqual(value, rasterRef.header->flag) || isEqual(aspect, aspectMap.header->flag)) + { + return false; + } int r = 0; int c = 0; - if (aspect > 135 && aspect < 225) + if (aspect >= 135 && aspect <= 225) r = 1; - else if ((aspect < 45) || (aspect > 315)) + else if ((aspect <= 45) || (aspect >= 315)) r = -1; - if (aspect > 45 && aspect < 135) + if (aspect >= 45 && aspect <= 135) c = 1; - else if (aspect > 225 && aspect < 315) + else if (aspect >= 225 && aspect <= 315) c = -1; float valueBoundary = rasterRef.getValueFromRowCol(row + r, col + c); diff --git a/meteo/meteo.h b/meteo/meteo.h index 648778fa..b57f8126 100644 --- a/meteo/meteo.h +++ b/meteo/meteo.h @@ -108,7 +108,7 @@ enum criteria3DVariable {volumetricWaterContent, waterTotalPotential, waterMatricPotential, availableWaterContent, degreeOfSaturation, soilTemperature, soilSurfaceMoisture, bottomDrainage, waterDeficit, waterInflow, waterOutflow, - factorOfSafety}; + factorOfSafety, minimumFactorOfSafety}; const std::map MapDailyMeteoVar = { From dd447de517b672afea461a7a51a47519c6e220dc Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 1 Jul 2024 20:09:09 +0200 Subject: [PATCH 106/179] add minimum factor of safety --- gis/color.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gis/color.cpp b/gis/color.cpp index 36fa33ec..41a3b634 100644 --- a/gis/color.cpp +++ b/gis/color.cpp @@ -210,7 +210,7 @@ bool setSlopeStabilityScale(Crit3DColorScale* myScale) myScale->keyColor[0] = Crit3DColor(128, 0, 128); /*!< violet */ myScale->keyColor[1] = Crit3DColor(255, 0, 0); /*!< red */ myScale->keyColor[2] = Crit3DColor(255, 255, 0); /*!< yellow */ - myScale->keyColor[3] = Crit3DColor(128, 220, 0); /*!< yellow/green */ + myScale->keyColor[3] = Crit3DColor(128, 196, 0); /*!< yellow/green */ myScale->keyColor[4] = Crit3DColor(64, 196, 64); /*!< green */ myScale->keyColor[5] = Crit3DColor(64, 196, 64); /*!< green */ myScale->keyColor[6] = Crit3DColor(64, 196, 64); /*!< green */ From 71ace544f1981df678f7b08ab86f00f66de6eee5 Mon Sep 17 00:00:00 2001 From: cate-to Date: Tue, 2 Jul 2024 16:50:52 +0200 Subject: [PATCH 107/179] fixed bug --- interpolation/interpolation.cpp | 10 ++++++---- mathFunctions/furtherMathFunctions.cpp | 2 +- project/project.cpp | 1 - 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 4e4d4a06..baa59232 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1364,22 +1364,22 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati if (mySettings->getChosenElevationFunction() == piecewiseTwo) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); - tempParam = {-200, min-2, 0, -0.015, 2000, max+2, 0.01, 0.0015}; + tempParam = {-200, min-2, 0, -0.01, 5000, max+2, 0.01, 0.0015}; } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); - tempParam = {-200, min-2, 100, 0, -0.015, -0.015, 2000, max+2, 1000, 0.007, 0.0015, 0.0015}; + tempParam = {-200, min-2, 100, 0, -0.01, -0.01, 5000, max+2, 1000, 0.007, 0.0015, 0.0015}; } else if (mySettings->getChosenElevationFunction() == piecewiseThree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - tempParam = {-200, min-2, 100, 0, -0.015, 2000, max+2, 1000, 0.007, 0.0015}; + tempParam = {-200, min-2, 100, 0, -0.01, 5000, max+2, 1000, 0.007, 0.0015}; } else if (mySettings->getChosenElevationFunction() == freiFree) { mySettings->getProxy(i)->setFittingFunctionName(freiFree); - tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 2000, 1000, 0.006}; + tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 5000, 1000, 0.006}; } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } @@ -1888,6 +1888,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorsetCurrentCombination(myCombination); mySettings->getProxy(pos)->setIsSignificant(false); + parameters.clear(); } } } @@ -1970,6 +1971,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorsetCurrentCombination(myCombination); mySettings->getProxy(pos)->setIsSignificant(false); + parameters.clear(); } } } diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 202b49b7..37249c63 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -2000,7 +2000,7 @@ namespace interpolation steps = {50.0, 0.5, 50.0, 0.00075, 0.00075, 0.00075}; else return false; - const int numSteps = 40; + const int numSteps = 100; int directions[] = {1, -1}; size_t numParamsToVary = parameters.size(); std::vector firstGuessParam = parameters; diff --git a/project/project.cpp b/project/project.cpp index 77444758..c425d196 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2729,7 +2729,6 @@ bool Project::interpolationGrid(meteoVariable myVar, const Crit3DTime& myTime) proxyIndex++; } } - if (interpolationSettings.getUseLocalDetrending()) { std::vector subsetInterpolationPoints; From 2017998ca40138145f96b7357c590c18a24071d7 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 2 Jul 2024 20:10:34 +0200 Subject: [PATCH 108/179] update 3D --- soil/soil.cpp | 7 ++++++- soil/soil.h | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/soil/soil.cpp b/soil/soil.cpp index 880c07f0..71279893 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -372,7 +372,12 @@ namespace soil if (horizon.organicMatter > 0.2) return 16; // OL else - return 13; // ML + { + if(horizon.texture.clay >= 20) + return 12; // SC-CL + else + return 13; // ML + } } if (horizon.texture.classNameUSDA == "clay" || horizon.texture.classNameUSDA == "silty clay") { diff --git a/soil/soil.h b/soil/soil.h index 9212ceee..a889c10e 100644 --- a/soil/soil.h +++ b/soil/soil.h @@ -134,14 +134,14 @@ double upperDepth, lowerDepth; /*!< [m] */ double coarseFragments; /*!< [-] 0-1 */ double organicMatter; /*!< [-] 0-1 */ - double bulkDensity; /*!< [g/cm^3] */ + double bulkDensity; /*!< [g cm-3] */ double effectiveCohesion; /*!< [kPa] */ double frictionAngle; /*!< [degrees] */ double fieldCapacity; /*!< [kPa] */ double wiltingPoint; /*!< [kPa] */ - double waterContentFC; /*!< [m^3 m^-3]*/ - double waterContentWP; /*!< [m^3 m^-3]*/ + double waterContentFC; /*!< [m3 m-3]*/ + double waterContentWP; /*!< [m3 m-3]*/ double PH; /*!< [-] */ double CEC; /*!< [meq/100g]*/ From 9eb8ef397e59bcfff9536313ec6d20848689d667 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 3 Jul 2024 16:25:06 +0200 Subject: [PATCH 109/179] fix date --- project/project.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index c425d196..d21de05d 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -916,9 +916,7 @@ Crit3DTime Project::getCrit3DCurrentTime() QDateTime Project::getCurrentTime() { - QDateTime myDateTime; - myDateTime.setDate(this->currentDate); - return myDateTime.addSecs(this->currentHour * HOUR_SECONDS); + return QDateTime(currentDate, QTime(currentHour, 0, 0), Qt::UTC); } From 6cf1bbe8873a05fe94d172f4ea31addce4e2ba23 Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Wed, 3 Jul 2024 16:54:01 +0200 Subject: [PATCH 110/179] changed multiple detrending --- interpolation/interpolation.cpp | 2 +- mathFunctions/furtherMathFunctions.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index baa59232..4e5f930c 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1472,7 +1472,7 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 proxyParamMin.push_back(min_); proxyParamMax.push_back(max_); proxyParamDelta.push_back((max_ - min_) / RATIO_DELTA); - proxyParamFirstGuess.push_back((max_ + min_) / 2); // TODO check if ok + proxyParamFirstGuess.push_back((max_ + min_) / 2); } paramMin.push_back(proxyParamMin); diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 90a6c8d9..9b818576 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -1994,13 +1994,14 @@ namespace interpolation //grigliato std::vector steps; + const int numSteps = 100; if (parameters.size() == 4) - steps = {50.0, 0.5, 0.00075, 0.00075}; + //steps = {50.0, 0.5, 0.00075, 0.00075}; + steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 2*(parametersMax[2]-parametersMin[2])/numSteps, 2*(parametersMax[3]-parametersMin[3])/numSteps}; else if (parameters.size() == 6) - steps = {50.0, 0.5, 50.0, 0.00075, 0.00075, 0.00075}; + steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 2*(parametersMax[2]-parametersMin[2])/numSteps, 2*(parametersMax[3]-parametersMin[3])/numSteps,2*(parametersMax[4]-parametersMin[4])/numSteps,2*(parametersMax[5]-parametersMin[5])/numSteps }; else return false; - const int numSteps = 100; int directions[] = {1, -1}; size_t numParamsToVary = parameters.size(); std::vector firstGuessParam = parameters; From 161c9b91922c886e78ae95f6822754623c36e0cc Mon Sep 17 00:00:00 2001 From: giadasan Date: Thu, 4 Jul 2024 16:48:55 +0200 Subject: [PATCH 111/179] tooltips soil table --- soilWidget/soilTable.cpp | 42 +++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/soilWidget/soilTable.cpp b/soilWidget/soilTable.cpp index 6b5c32c7..67e17091 100644 --- a/soilWidget/soilTable.cpp +++ b/soilWidget/soilTable.cpp @@ -47,13 +47,45 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) if (type == dbTable) { - QTableWidgetItem *currentHeaderItem = this->horizontalHeaderItem(2); + QTableWidgetItem *currentHeaderItem = horizontalHeaderItem(2); if (currentHeaderItem) currentHeaderItem->setToolTip("Percentage of sand (from 2.0 to 0.05 mm)"); - //currentHeaderItem = this->horizontalHeaderItem(3); - //.. - // TODO + currentHeaderItem = horizontalHeaderItem(3); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of silt (from 0.05 to 0.002 mm)"); + + currentHeaderItem = this->horizontalHeaderItem(4); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of clay (minor than 0.002 mm)"); + + currentHeaderItem = this->horizontalHeaderItem(5); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of coarse fragments (major than 2.0 mm)"); + + currentHeaderItem = this->horizontalHeaderItem(6); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of organic matter"); + + currentHeaderItem = this->horizontalHeaderItem(7); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Bulk density"); + + currentHeaderItem = this->horizontalHeaderItem(8); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Saturated hydraulic conductivity"); + + currentHeaderItem = this->horizontalHeaderItem(9); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Water content at saturation"); + + currentHeaderItem = this->horizontalHeaderItem(10); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Effective cohesion"); + + currentHeaderItem = this->horizontalHeaderItem(11); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Soil friction angle"); } else if (type == modelTable) { @@ -77,7 +109,7 @@ void Crit3DSoilTable::mouseMoveEvent(QMouseEvent *event) } else if (type == modelTable) { - QToolTip::showText(this->viewport()->mapToGlobal(pos), "wrong horizon", this, QRect(pos,QSize(100,100)), 800); + QToolTip::showText(this->viewport()->mapToGlobal(pos), "wrong horizon or missing db", this, QRect(pos,QSize(100,100)), 800); } } else if(item->background().color() == Qt::yellow) From cac39623296fe412ac0c3832a2aeb2cb1c2cf436 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 4 Jul 2024 17:17:49 +0200 Subject: [PATCH 112/179] update tooltip --- criteria1DWidget/tabIrrigation.cpp | 2 +- criteria1DWidget/tabLAI.cpp | 31 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/criteria1DWidget/tabIrrigation.cpp b/criteria1DWidget/tabIrrigation.cpp index d28a46c8..3f9f4d26 100644 --- a/criteria1DWidget/tabIrrigation.cpp +++ b/criteria1DWidget/tabIrrigation.cpp @@ -262,7 +262,7 @@ void TabIrrigation::tooltipEvapTransp(QPointF point, bool isShow) QDate xDate(firstYear, 1, 1); int doy = int(round(point.x())); xDate = xDate.addDays(doy); - m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + "evap/transp. " + QString::number(point.y(),'f', 2)+ "mm"); + m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + QString::number(point.y(),'f', 2)+ "mm"); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); diff --git a/criteria1DWidget/tabLAI.cpp b/criteria1DWidget/tabLAI.cpp index f88eba87..c079321c 100644 --- a/criteria1DWidget/tabLAI.cpp +++ b/criteria1DWidget/tabLAI.cpp @@ -18,25 +18,26 @@ TabLAI::TabLAI() chartView->setChart(chart); seriesLAI = new QLineSeries(); + seriesETP = new QLineSeries(); + seriesMaxTransp = new QLineSeries(); + seriesMaxEvap = new QLineSeries(); + seriesLAI->setName("Leaf Area Index [m2 m-2] "); + seriesETP->setName("Potential evapotranspiration [mm] "); + seriesMaxTransp->setName("Maximum transpiration [mm] "); + seriesMaxEvap->setName("Maximum evaporation [mm] "); + QPen pen; pen.setWidth(2); seriesLAI->setPen(pen); - seriesLAI->setColor(QColor(0, 200, 0, 255)); - seriesETP = new QLineSeries(); - seriesETP->setName("Potential evapotranspiration [mm] "); - // bug with black - seriesETP->setColor(QColor(0, 0, 1, 255)); - - seriesMaxTransp = new QLineSeries(); - seriesMaxTransp->setName("Maximum transpiration [mm] "); + seriesLAI->setColor(QColor(0, 200, 0, 255)); seriesMaxTransp->setColor(QColor(Qt::red)); - - seriesMaxEvap = new QLineSeries(); - seriesMaxEvap->setName("Maximum evaporation [mm] "); seriesMaxEvap->setColor(QColor(Qt::blue)); + // bug with black + seriesETP->setColor(QColor(0, 0, 16, 255)); + axisX = new QDateTimeAxis(); axisY = new QValueAxis(); axisYdx = new QValueAxis(); @@ -201,7 +202,7 @@ void TabLAI::tooltipLAI(QPointF point, bool state) { QDateTime xDate; xDate.setMSecsSinceEpoch(point.x()); - m_tooltip->setText(QString("%1 \nLAI: %2 ").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nLAI: %2 [m2 m-2]").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -217,7 +218,7 @@ void TabLAI::tooltipPE(QPointF point, bool state) { QDateTime xDate; xDate.setMSecsSinceEpoch(point.x()); - m_tooltip->setText(QString("%1 \nPot. ET: %2 ").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nETP: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -233,7 +234,7 @@ void TabLAI::tooltipME(QPointF point, bool state) { QDateTime xDate; xDate.setMSecsSinceEpoch(point.x()); - m_tooltip->setText(QString("%1 \nEvap. max: %2 ").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nEvaporation max.: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -250,7 +251,7 @@ void TabLAI::tooltipMaxTranspiration(QPointF point, bool state) { QDateTime xDate; xDate.setMSecsSinceEpoch(point.x()); - m_tooltip->setText(QString("%1 \nTransp. max: %2 ").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nTranspiration max.: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); From 7b578217331cfc0344d357707c072d49d2b1ede9 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 4 Jul 2024 17:24:07 +0200 Subject: [PATCH 113/179] update tooltip --- criteria1DWidget/tabIrrigation.cpp | 10 +++++----- criteria1DWidget/tabLAI.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/criteria1DWidget/tabIrrigation.cpp b/criteria1DWidget/tabIrrigation.cpp index 3f9f4d26..d07a1759 100644 --- a/criteria1DWidget/tabIrrigation.cpp +++ b/criteria1DWidget/tabIrrigation.cpp @@ -65,7 +65,7 @@ TabIrrigation::TabIrrigation() axisY->setRange(0,8); axisY->setTickCount(9); - axisYdx->setTitleText("Prec - Irrigation [mm]"); + axisYdx->setTitleText("Precipitation - Irrigation [mm]"); axisYdx->setTitleFont(font); axisYdx->setRange(0,40); axisYdx->setTickCount(9); @@ -241,7 +241,7 @@ void TabIrrigation::tooltipLAI(QPointF point, bool isShow) QDate xDate(firstYear, 1, 1); int doy = int(round(point.x())); // start from 0 xDate = xDate.addDays(doy); - m_tooltip->setText(QString("%1 \nLAI %2 ").arg(xDate.toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nLAI: %2 [m2 m-2]").arg(xDate.toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -262,7 +262,7 @@ void TabIrrigation::tooltipEvapTransp(QPointF point, bool isShow) QDate xDate(firstYear, 1, 1); int doy = int(round(point.x())); xDate = xDate.addDays(doy); - m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + QString::number(point.y(),'f', 2)+ "mm"); + m_tooltip->setText(xDate.toString("yyyy-MM-dd") + "\n" + QString::number(point.y(),'f', 2)+ " mm"); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -292,11 +292,11 @@ void TabIrrigation::tooltipPrecIrr(bool isShow, int index, QBarSet *barset) QString valueStr; if (barset->label() == "Precipitation [mm]") { - valueStr = QString("%1 \nPrecipitation [mm] %2 ").arg(xDate.toString("yyyy-MM-dd")).arg(barset->at(index), 0, 'f', 1); + valueStr = QString("%1\nPrecipitation: %2 mm").arg(xDate.toString("yyyy-MM-dd")).arg(barset->at(index), 0, 'f', 1); } else if (barset->label() == "Irrigation [mm]") { - valueStr = QString("%1 \nIrrigation [mm] %2 ").arg(xDate.toString("yyyy-MM-dd")).arg(barset->at(index), 0, 'f', 1); + valueStr = QString("%1\nIrrigation: %2 mm").arg(xDate.toString("yyyy-MM-dd")).arg(barset->at(index), 0, 'f', 1); } m_tooltip->setText(valueStr); diff --git a/criteria1DWidget/tabLAI.cpp b/criteria1DWidget/tabLAI.cpp index c079321c..3fe8ae30 100644 --- a/criteria1DWidget/tabLAI.cpp +++ b/criteria1DWidget/tabLAI.cpp @@ -234,7 +234,7 @@ void TabLAI::tooltipME(QPointF point, bool state) { QDateTime xDate; xDate.setMSecsSinceEpoch(point.x()); - m_tooltip->setText(QString("%1\nEvaporation max.: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nmax. Evaporation: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); @@ -251,7 +251,7 @@ void TabLAI::tooltipMaxTranspiration(QPointF point, bool state) { QDateTime xDate; xDate.setMSecsSinceEpoch(point.x()); - m_tooltip->setText(QString("%1\nTranspiration max.: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); + m_tooltip->setText(QString("%1\nmax. Transpiration: %2 mm").arg(xDate.date().toString("yyyy-MM-dd")).arg(point.y(), 0, 'f', 1)); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); m_tooltip->updateGeometry(); From 3abfff0b1f3f83a41154f73c8c2848c056004587 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 4 Jul 2024 20:00:51 +0200 Subject: [PATCH 114/179] fix double validator --- pointStatisticsWidget/dialogElaboration.cpp | 8 +-- pragaProject/dialogMeteoComputation.cpp | 10 ++-- pragaProject/saveClimaLayout.cpp | 59 +++++++++++---------- pragaProject/saveClimaLayout.h | 30 +++++------ 4 files changed, 50 insertions(+), 57 deletions(-) diff --git a/pointStatisticsWidget/dialogElaboration.cpp b/pointStatisticsWidget/dialogElaboration.cpp index 706db6c7..c384e4a3 100644 --- a/pointStatisticsWidget/dialogElaboration.cpp +++ b/pointStatisticsWidget/dialogElaboration.cpp @@ -175,13 +175,9 @@ DialogElaboration::DialogElaboration(QSettings *settings, Crit3DClimate *clima, settings->endGroup(); elaborationLayout.addWidget(&elaborationList); - QLocale local(QLocale::system().language()); - local.setNumberOptions(QLocale::RejectGroupSeparator); elab1Parameter.setPlaceholderText("Parameter"); elab1Parameter.setFixedWidth(90); - QDoubleValidator* validator = new QDoubleValidator(-9999.0, 9999.0, 2); - validator->setLocale(local); - elab1Parameter.setValidator(validator); + elab1Parameter.setValidator(new QDoubleValidator(-9999.0, 9999.0, 2)); QString elab1Field = elaborationList.currentText(); if ( MapElabWithParam.find(elab1Field.toStdString()) == MapElabWithParam.end()) @@ -272,7 +268,7 @@ void DialogElaboration::done(bool res) clima->setElab1(elaborationList.currentText()); clima->setParam1IsClimate(false); - if (elab1Parameter.text() != "") + if (! elab1Parameter.text().isEmpty()) { clima->setParam1(elab1Parameter.text().toFloat()); } diff --git a/pragaProject/dialogMeteoComputation.cpp b/pragaProject/dialogMeteoComputation.cpp index 39ddce59..548fa622 100644 --- a/pragaProject/dialogMeteoComputation.cpp +++ b/pragaProject/dialogMeteoComputation.cpp @@ -275,13 +275,9 @@ DialogMeteoComputation::DialogMeteoComputation(QSettings *settings, bool isMeteo settings->endGroup(); elaborationLayout.addWidget(&elaborationList); - QLocale local(QLocale::system().language()); - local.setNumberOptions(QLocale::RejectGroupSeparator); elab1Parameter.setPlaceholderText("Parameter"); elab1Parameter.setFixedWidth(90); - QDoubleValidator* validator = new QDoubleValidator(-9999.0, 9999.0, 2); - validator->setLocale(local); - elab1Parameter.setValidator(validator); + elab1Parameter.setValidator(new QDoubleValidator(-9999.0, 9999.0, 2)); readParam.setText("Read param from db Climate"); readParam.setChecked(false); climateDbElabList.setVisible(false); @@ -331,7 +327,7 @@ DialogMeteoComputation::DialogMeteoComputation(QSettings *settings, bool isMeteo elab2Parameter.setPlaceholderText("Parameter"); elab2Parameter.setFixedWidth(90); - elab2Parameter.setValidator(validator); + elab2Parameter.setValidator(new QDoubleValidator(-9999.0, 9999.0, 2)); QString elab2Field = secondElabList.currentText(); if ( MapElabWithParam.find(elab2Field.toStdString()) == MapElabWithParam.end()) @@ -567,7 +563,7 @@ void DialogMeteoComputation::done(bool res) if (!readParam.isChecked()) { myProject.clima->setParam1IsClimate(false); - if (elab1Parameter.text() != "") + if (! elab1Parameter.text().isEmpty()) { myProject.clima->setParam1(elab1Parameter.text().toFloat()); } diff --git a/pragaProject/saveClimaLayout.cpp b/pragaProject/saveClimaLayout.cpp index 536c1595..b8c49b24 100644 --- a/pragaProject/saveClimaLayout.cpp +++ b/pragaProject/saveClimaLayout.cpp @@ -45,7 +45,8 @@ void SaveClimaLayout::addElab() QString elabAdded = firstYear + "-" + lastYear + "_" + variable.remove("_") + "_" + period; if (period == "Generic") { - elabAdded = elabAdded + "_" + genericPeriodStartDay + "of" + genericPeriodStartMonth + "-" + genericPeriodEndDay + "of" + genericPeriodEndMonth; + elabAdded = elabAdded + "_" + genericPeriodStartDay + "of" + genericPeriodStartMonth + + "-" + genericPeriodEndDay + "of" + genericPeriodEndMonth; if (genericNYear != "0") { elabAdded = elabAdded + "-+" + genericNYear + "y"; @@ -152,9 +153,9 @@ QList SaveClimaLayout::getList() const return list; } -void SaveClimaLayout::setList(const QList &value) +void SaveClimaLayout::setList(const QList &valueList) { - list = value; + list = valueList; listView.addItems(list); } @@ -163,9 +164,9 @@ QString SaveClimaLayout::getElab1ParamFromdB() const return elab1ParamFromdB; } -void SaveClimaLayout::setElab1ParamFromdB(const QString &value) +void SaveClimaLayout::setElab1ParamFromdB(const QString &valueStr) { - elab1ParamFromdB = value; + elab1ParamFromdB = valueStr; } QString SaveClimaLayout::getFirstYear() const @@ -173,9 +174,9 @@ QString SaveClimaLayout::getFirstYear() const return firstYear; } -void SaveClimaLayout::setFirstYear(const QString &value) +void SaveClimaLayout::setFirstYear(const QString &valueStr) { - firstYear = value; + firstYear = valueStr; } QString SaveClimaLayout::getLastYear() const @@ -183,9 +184,9 @@ QString SaveClimaLayout::getLastYear() const return lastYear; } -void SaveClimaLayout::setLastYear(const QString &value) +void SaveClimaLayout::setLastYear(const QString &valueStr) { - lastYear = value; + lastYear = valueStr; } QString SaveClimaLayout::getVariable() const @@ -193,9 +194,9 @@ QString SaveClimaLayout::getVariable() const return variable; } -void SaveClimaLayout::setVariable(const QString &value) +void SaveClimaLayout::setVariable(const QString &valueStr) { - variable = value; + variable = valueStr; } QString SaveClimaLayout::getPeriod() const @@ -203,9 +204,9 @@ QString SaveClimaLayout::getPeriod() const return period; } -void SaveClimaLayout::setPeriod(const QString &value) +void SaveClimaLayout::setPeriod(const QString &valueStr) { - period = value; + period = valueStr; } QString SaveClimaLayout::getGenericPeriodStartDay() const @@ -223,9 +224,9 @@ QString SaveClimaLayout::getGenericPeriodStartMonth() const return genericPeriodStartMonth; } -void SaveClimaLayout::setGenericPeriodStartMonth(const QString &value) +void SaveClimaLayout::setGenericPeriodStartMonth(const QString &valueStr) { - genericPeriodStartMonth = value; + genericPeriodStartMonth = valueStr; } QString SaveClimaLayout::getGenericPeriodEndDay() const @@ -233,9 +234,9 @@ QString SaveClimaLayout::getGenericPeriodEndDay() const return genericPeriodEndDay; } -void SaveClimaLayout::setGenericPeriodEndDay(const QString &value) +void SaveClimaLayout::setGenericPeriodEndDay(const QString &valueStr) { - genericPeriodEndDay = value; + genericPeriodEndDay = valueStr; } QString SaveClimaLayout::getGenericPeriodEndMonth() const @@ -243,9 +244,9 @@ QString SaveClimaLayout::getGenericPeriodEndMonth() const return genericPeriodEndMonth; } -void SaveClimaLayout::setGenericPeriodEndMonth(const QString &value) +void SaveClimaLayout::setGenericPeriodEndMonth(const QString &valueStr) { - genericPeriodEndMonth = value; + genericPeriodEndMonth = valueStr; } QString SaveClimaLayout::getGenericNYear() const @@ -253,9 +254,9 @@ QString SaveClimaLayout::getGenericNYear() const return genericNYear; } -void SaveClimaLayout::setGenericNYear(const QString &value) +void SaveClimaLayout::setGenericNYear(const QString &valueStr) { - genericNYear = value; + genericNYear = valueStr; } QString SaveClimaLayout::getSecondElab() const @@ -263,9 +264,9 @@ QString SaveClimaLayout::getSecondElab() const return secondElab; } -void SaveClimaLayout::setSecondElab(const QString &value) +void SaveClimaLayout::setSecondElab(const QString &valueStr) { - secondElab = value; + secondElab = valueStr; } QString SaveClimaLayout::getElab2Param() const @@ -273,9 +274,9 @@ QString SaveClimaLayout::getElab2Param() const return elab2Param; } -void SaveClimaLayout::setElab2Param(const QString &value) +void SaveClimaLayout::setElab2Param(const QString &valueStr) { - elab2Param = value; + elab2Param = valueStr; } QString SaveClimaLayout::getElab() const @@ -283,9 +284,9 @@ QString SaveClimaLayout::getElab() const return elab; } -void SaveClimaLayout::setElab(const QString &value) +void SaveClimaLayout::setElab(const QString &valueStr) { - elab = value; + elab = valueStr; } QString SaveClimaLayout::getElab1Param() const @@ -293,7 +294,7 @@ QString SaveClimaLayout::getElab1Param() const return elab1Param; } -void SaveClimaLayout::setElab1Param(const QString &value) +void SaveClimaLayout::setElab1Param(const QString &valueStr) { - elab1Param = value; + elab1Param = valueStr; } diff --git a/pragaProject/saveClimaLayout.h b/pragaProject/saveClimaLayout.h index e76ee492..22098c25 100644 --- a/pragaProject/saveClimaLayout.h +++ b/pragaProject/saveClimaLayout.h @@ -16,33 +16,33 @@ class SaveClimaLayout : public QDialog SaveClimaLayout(); QString getFirstYear() const; - void setFirstYear(const QString &value); + void setFirstYear(const QString &valueStr); QString getLastYear() const; - void setLastYear(const QString &value); + void setLastYear(const QString &valueStr); QString getVariable() const; - void setVariable(const QString &value); + void setVariable(const QString &valueStr); QString getPeriod() const; - void setPeriod(const QString &value); + void setPeriod(const QString &valueStr); QString getGenericPeriodEnd() const; - void setGenericPeriodEnd(const QString &value); + void setGenericPeriodEnd(const QString &valueStr); QString getGenericNYear() const; - void setGenericNYear(const QString &value); + void setGenericNYear(const QString &valueStr); QString getSecondElab() const; - void setSecondElab(const QString &value); + void setSecondElab(const QString &valueStr); QString getElab2Param() const; - void setElab2Param(const QString &value); + void setElab2Param(const QString &valueStr); QString getElab() const; - void setElab(const QString &value); + void setElab(const QString &valueStr); QString getElab1Param() const; - void setElab1Param(const QString &value); + void setElab1Param(const QString &valueStr); QString getGenericPeriodStartDay() const; void setGenericPeriodStartDay(const QString &value); QString getGenericPeriodStartMonth() const; - void setGenericPeriodStartMonth(const QString &value); + void setGenericPeriodStartMonth(const QString &valueStr); QString getGenericPeriodEndDay() const; - void setGenericPeriodEndDay(const QString &value); + void setGenericPeriodEndDay(const QString &valueStr); QString getGenericPeriodEndMonth() const; - void setGenericPeriodEndMonth(const QString &value); + void setGenericPeriodEndMonth(const QString &valueStr); void addElab(); void deleteRaw(); @@ -52,10 +52,10 @@ class SaveClimaLayout : public QDialog void loadElabList(); QList getList() const; - void setList(const QList &value); + void setList(const QList &valueList); QString getElab1ParamFromdB() const; - void setElab1ParamFromdB(const QString &value); + void setElab1ParamFromdB(const QString &valueStr); private: From ba8d4887d123e775d7f732c132fdd3b77e1692d0 Mon Sep 17 00:00:00 2001 From: giadasan Date: Fri, 5 Jul 2024 10:43:32 +0200 Subject: [PATCH 115/179] tooltips soil model table --- soilWidget/soilTable.cpp | 56 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/soilWidget/soilTable.cpp b/soilWidget/soilTable.cpp index 67e17091..711a7bf6 100644 --- a/soilWidget/soilTable.cpp +++ b/soilWidget/soilTable.cpp @@ -77,11 +77,11 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) currentHeaderItem = this->horizontalHeaderItem(9); if (currentHeaderItem) - currentHeaderItem->setToolTip("Water content at saturation"); + currentHeaderItem->setToolTip("Water content at saturation (SAT)"); currentHeaderItem = this->horizontalHeaderItem(10); if (currentHeaderItem) - currentHeaderItem->setToolTip("Effective cohesion"); + currentHeaderItem->setToolTip("Soil effective cohesion"); currentHeaderItem = this->horizontalHeaderItem(11); if (currentHeaderItem) @@ -89,7 +89,57 @@ Crit3DSoilTable::Crit3DSoilTable(tableType type) : type(type) } else if (type == modelTable) { - // TODO + QTableWidgetItem *currentHeaderItem = horizontalHeaderItem(0); + if (currentHeaderItem) + currentHeaderItem->setToolTip("USDA textural soil classification"); + + currentHeaderItem = horizontalHeaderItem(1); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of coarse fragments (major than 2.0 mm)"); + + currentHeaderItem = this->horizontalHeaderItem(2); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Percentage of organic matter"); + + currentHeaderItem = this->horizontalHeaderItem(3); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Bulk density"); + + currentHeaderItem = this->horizontalHeaderItem(4); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Saturated hydraulic conductivity"); + + currentHeaderItem = this->horizontalHeaderItem(5); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Water content at saturation (SAT)"); + + currentHeaderItem = this->horizontalHeaderItem(6); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Water content at wilting point (WP)"); + + currentHeaderItem = this->horizontalHeaderItem(7); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Air entry value"); + + currentHeaderItem = this->horizontalHeaderItem(8); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Van Genuchten parameter ฮฑ"); + + currentHeaderItem = this->horizontalHeaderItem(9); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Van Genuchten parameter n"); + + currentHeaderItem = this->horizontalHeaderItem(10); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Van Genuchten parameter m"); + + currentHeaderItem = this->horizontalHeaderItem(11); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Soil effective cohesion"); + + currentHeaderItem = this->horizontalHeaderItem(12); + if (currentHeaderItem) + currentHeaderItem->setToolTip("Soil friction angle"); } } From d31b8e45cd226f89a198b4e8b21d6d58d4df7865 Mon Sep 17 00:00:00 2001 From: giadasan Date: Fri, 5 Jul 2024 13:57:11 +0200 Subject: [PATCH 116/179] set validity limits for geotechnical parameters and fix table model --- soilWidget/soilWidget.cpp | 2 +- soilWidget/tabHorizons.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soilWidget/soilWidget.cpp b/soilWidget/soilWidget.cpp index 6db0ea06..379c6278 100644 --- a/soilWidget/soilWidget.cpp +++ b/soilWidget/soilWidget.cpp @@ -293,7 +293,7 @@ void Crit3DSoilWidget::setDbSoil(QSqlDatabase dbOpened, QString soilCode) // load default geotechnics parameters (not mandatory) if (! loadGeotechnicsParameters(dbSoil, geotechnicsClassList, errorStr)) { - QMessageBox::warning(nullptr, "Warning", "loadGeotechnicsParameters\n" + errorStr); + QMessageBox::warning(nullptr, "Warning", "Failed to load geotecnical parameters for slope stability: missing reference db"); } // read soil list diff --git a/soilWidget/tabHorizons.cpp b/soilWidget/tabHorizons.cpp index 51e1430a..835c9c20 100644 --- a/soilWidget/tabHorizons.cpp +++ b/soilWidget/tabHorizons.cpp @@ -275,7 +275,7 @@ bool TabHorizons::checkDepths() for (int horizonNum = 0; horizonNumrowCount(); horizonNum++) { //except first row - if ( horizonNum > 0) + if (horizonNum > 0) { if (mySoil->horizon[unsigned(horizonNum)].dbData.upperDepth != mySoil->horizon[horizonNum-1].dbData.lowerDepth) { @@ -366,12 +366,12 @@ bool TabHorizons::checkHorizonData(int horizonNum) tableDb->item(horizonNum,9)->setBackground(Qt::red); } - if (dbData->effectiveCohesion != NODATA && (dbData->effectiveCohesion < 0)) + if (dbData->effectiveCohesion != NODATA && (dbData->effectiveCohesion < 0 || dbData->effectiveCohesion > 110)) { tableDb->item(horizonNum,10)->setBackground(Qt::red); } - if (dbData->frictionAngle != NODATA && (dbData->frictionAngle < 0)) + if (dbData->frictionAngle != NODATA && (dbData->frictionAngle < 0 || dbData->frictionAngle > 50)) { tableDb->item(horizonNum,11)->setBackground(Qt::red); } From 10f3360ad34fce7a95687346178417571babfa21 Mon Sep 17 00:00:00 2001 From: giadasan Date: Fri, 5 Jul 2024 14:09:11 +0200 Subject: [PATCH 117/179] set validity limits for geotechnical parameters and fix table model --- soilWidget/tabHorizons.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/soilWidget/tabHorizons.cpp b/soilWidget/tabHorizons.cpp index 835c9c20..b721b63c 100644 --- a/soilWidget/tabHorizons.cpp +++ b/soilWidget/tabHorizons.cpp @@ -462,14 +462,15 @@ void TabHorizons::checkComputedValues(int horizonNum) tableModel->item(horizonNum,5)->setBackground(Qt::yellow); } - if (horizon->dbData.effectiveCohesion == NODATA) + // for soil mechanics parameters just check if is missing + if (horizon->geotechnics.effectiveCohesion == NODATA) { - tableModel->item(horizonNum,11)->setBackground(Qt::yellow); + tableModel->item(horizonNum,11)->setBackground(Qt::red); } - if (horizon->dbData.frictionAngle == NODATA) + if (horizon->geotechnics.frictionAngle == NODATA) { - tableModel->item(horizonNum,12)->setBackground(Qt::yellow); + tableModel->item(horizonNum,12)->setBackground(Qt::red); } } From 7ffb97657b74305b25217fb0035db6f391b1953b Mon Sep 17 00:00:00 2001 From: giadasan Date: Fri, 5 Jul 2024 16:11:26 +0200 Subject: [PATCH 118/179] fix soil model table --- criteria1DWidget/tabIrrigation.cpp | 2 -- soilWidget/tabHorizons.cpp | 9 ++++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/criteria1DWidget/tabIrrigation.cpp b/criteria1DWidget/tabIrrigation.cpp index d07a1759..8d64d5a3 100644 --- a/criteria1DWidget/tabIrrigation.cpp +++ b/criteria1DWidget/tabIrrigation.cpp @@ -253,8 +253,6 @@ void TabIrrigation::tooltipLAI(QPointF point, bool isShow) } } - -// TODO Giada void TabIrrigation::tooltipEvapTransp(QPointF point, bool isShow) { if (isShow) diff --git a/soilWidget/tabHorizons.cpp b/soilWidget/tabHorizons.cpp index b721b63c..eed115fa 100644 --- a/soilWidget/tabHorizons.cpp +++ b/soilWidget/tabHorizons.cpp @@ -462,15 +462,14 @@ void TabHorizons::checkComputedValues(int horizonNum) tableModel->item(horizonNum,5)->setBackground(Qt::yellow); } - // for soil mechanics parameters just check if is missing - if (horizon->geotechnics.effectiveCohesion == NODATA) + if (abs(horizon->dbData.effectiveCohesion - horizon->effectiveCohesion) > EPSILON) { - tableModel->item(horizonNum,11)->setBackground(Qt::red); + tableModel->item(horizonNum,11)->setBackground(Qt::yellow); } - if (horizon->geotechnics.frictionAngle == NODATA) + if (abs(horizon->dbData.frictionAngle - horizon->frictionAngle) > EPSILON) { - tableModel->item(horizonNum,12)->setBackground(Qt::red); + tableModel->item(horizonNum,12)->setBackground(Qt::yellow); } } From c2cd89a471339e4183b34e1474978fab5307250f Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 5 Jul 2024 19:53:51 +0200 Subject: [PATCH 119/179] add clip raster --- gis/gis.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ gis/gis.h | 4 +++ 2 files changed, 79 insertions(+) diff --git a/gis/gis.cpp b/gis/gis.cpp index f73f6405..799eab10 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -1697,5 +1697,80 @@ namespace gis return true; } + + + bool clipRasterWithRaster(gis::Crit3DRasterGrid* refRaster, gis::Crit3DRasterGrid* maskRaster, gis::Crit3DRasterGrid* outputRaster) + { + if (refRaster == nullptr || maskRaster == nullptr || outputRaster == nullptr) + return false; + + gis::Crit3DRasterGrid* tmpRaster = new gis::Crit3DRasterGrid(); + tmpRaster->initializeGrid(*(refRaster->header)); + + bool isFirst = true; + long firstRow, lastRow, firstCol, lastCol; + double x, y; + for (long row = 0; row < refRaster->header->nrRows; row++) + { + for (long col = 0; col < refRaster->header->nrCols; col++) + { + gis::getUtmXYFromRowCol(refRaster->header, row, col, &x, &y); + if (! isEqual(maskRaster->getValueFromXY(x, y), maskRaster->header->flag)) + { + tmpRaster->value[row][col] = refRaster->value[row][col]; + if (isFirst) + { + firstRow = row; + lastRow = row; + firstCol = col; + lastCol = col; + isFirst = false; + } + else + { + firstRow = std::min(firstRow, row); + firstCol = std::min(firstCol, col); + lastRow = std::max(lastRow, row); + lastCol = std::max(lastCol, col); + } + } + } + } + + // check no data + if (isFirst) + { + tmpRaster->clear(); + return false; + } + + // new header + gis::Crit3DRasterHeader header; + header = *(refRaster->header); + header.nrRows = lastRow - firstRow + 1; + header.nrCols = lastCol - firstCol + 1; + header.llCorner.x = refRaster->header->llCorner.x + refRaster->header->cellSize * firstCol; + header.llCorner.y = refRaster->header->llCorner.y + refRaster->header->cellSize * (refRaster->header->nrRows - (lastRow +1)); + + // output raster + outputRaster->initializeGrid(header); + + for (long row = 0; row < outputRaster->header->nrRows; row++) + { + for (long col = 0; col < outputRaster->header->nrCols; col++) + { + float value = tmpRaster->value[row + firstRow][col + firstCol]; + if (! isEqual (value, tmpRaster->header->flag)) + outputRaster->value[row][col] = value; + } + } + + // clean memory + tmpRaster->clear(); + + gis::updateMinMaxRasterGrid(outputRaster); + return true; + } + } diff --git a/gis/gis.h b/gis/gis.h index 221e693d..2b6449fc 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -262,9 +262,13 @@ bool mapAlgebra(Crit3DRasterGrid* myMap1, Crit3DRasterGrid* myMap2, Crit3DRasterGrid *outputMap, operationType myOperation); bool mapAlgebra(Crit3DRasterGrid* myMap1, float myValue, Crit3DRasterGrid *outputMap, operationType myOperation); + bool prevailingMap(const Crit3DRasterGrid& inputMap, Crit3DRasterGrid *outputMap); float prevailingValue(const std::vector &valueList); + bool clipRasterWithRaster(gis::Crit3DRasterGrid* refRaster, gis::Crit3DRasterGrid* maskRaster, + gis::Crit3DRasterGrid* outputRaster); + bool computeLatLonMaps(const gis::Crit3DRasterGrid& rasterGrid, gis::Crit3DRasterGrid* latMap, gis::Crit3DRasterGrid* lonMap, const gis::Crit3DGisSettings& gisSettings); From 116bb60ea40c12d8691207fae79b05892df6f674 Mon Sep 17 00:00:00 2001 From: ftomei Date: Sun, 7 Jul 2024 16:47:11 +0200 Subject: [PATCH 120/179] update meteoWidget --- gis/gisIO.cpp | 2 +- graphics/stationMarker.cpp | 209 ++++++++++++++----------------- graphics/stationMarker.h | 46 +++++-- meteoWidget/dialogMeteoTable.cpp | 1 - meteoWidget/meteoWidget.cpp | 54 ++++++-- meteoWidget/meteoWidget.h | 2 + project/project.cpp | 8 +- soil/soil.cpp | 2 +- soilWidget/soilWidget.cpp | 2 +- soilWidget/soilWidget.pro | 1 - 10 files changed, 184 insertions(+), 143 deletions(-) diff --git a/gis/gisIO.cpp b/gis/gisIO.cpp index d09fda69..c4e82984 100644 --- a/gis/gisIO.cpp +++ b/gis/gisIO.cpp @@ -571,7 +571,7 @@ namespace gis } myFile << "ENVI\n"; - myFile << "description = {CRITERIA3D raster grid}\n"; + myFile << "description = {raster grid}\n"; myFile << "samples = " << rasterGrid->header->nrCols << "\n"; myFile << "lines = " << rasterGrid->header->nrRows << "\n"; myFile << "bands = 1\n"; diff --git a/graphics/stationMarker.cpp b/graphics/stationMarker.cpp index 233edb7d..7faae038 100644 --- a/graphics/stationMarker.cpp +++ b/graphics/stationMarker.cpp @@ -12,64 +12,18 @@ StationMarker::StationMarker(qreal radius,bool sizeIsZoomInvariant, QColor fillC this->setFlag(MapGraphicsObject::ObjectIsSelectable, false); this->setFlag(MapGraphicsObject::ObjectIsMovable, false); this->setFlag(MapGraphicsObject::ObjectIsFocusable, false); + _id = ""; _name = ""; _dataset = ""; + _municipality = ""; _altitude = NODATA; _lapseRateCode = primary; - _municipality = ""; - _active = true; -} - -void StationMarker::setId(std::string id) -{ - _id = id; -} - -std::string StationMarker::id() const -{ - return _id; -} - -void StationMarker::setName(const std::string &name) -{ - _name = name; -} - -void StationMarker::setDataset(const std::string &dataset) -{ - _dataset = dataset; -} - -void StationMarker::setAltitude(double altitude) -{ - _altitude = altitude; -} - -void StationMarker::setLapseRateCode(lapseRateCodeType code) -{ - _lapseRateCode = code; -} - -void StationMarker::setMunicipality(const std::string &municipality) -{ - _municipality = municipality; -} - -void StationMarker::setQuality(const quality::qualityType &quality) -{ - _quality = quality; -} -bool StationMarker::active() const -{ - return _active; + _caller = PRAGA_caller; + _active = true; } -void StationMarker::setActive(bool active) -{ - _active = active; -} void StationMarker::setToolTip() { @@ -109,74 +63,101 @@ void StationMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::RightButton) { - bool isGrid = false; - QMenu menu; - QAction *openMeteoWidget = menu.addAction("Open new meteo widget"); - QAction *appendMeteoWidget = menu.addAction("Append to last meteo widget"); - menu.addSeparator(); - QAction *openPointStatisticsWidget = menu.addAction("Open point statistics widget"); - QAction *openHomogeneityWidget = menu.addAction("Open homogeneity test widget"); - menu.addSeparator(); - QAction *openSynchronicityWidget = menu.addAction("Open synchronicity test widget"); - QAction *setSynchronicityReferencePoint = menu.addAction("Set as synchronicity reference point"); - menu.addSeparator(); - QMenu *orogCodeSubMenu; - orogCodeSubMenu = menu.addMenu("Orog code"); - QAction *actionOrogCode_primary = orogCodeSubMenu->addAction( "Set as primary station" ); - QAction *actionOrogCode_secondary = orogCodeSubMenu->addAction( "Set as secondary station" ); - QAction *actionOrogCode_supplemental = orogCodeSubMenu->addAction( "Set as supplemental station" ); - menu.addSeparator(); - QAction *actionMarkPoint = menu.addAction( "Mark point" ); - QAction *actionUnmarkPoint = menu.addAction( "Unmark point" ); - - QAction *selection = menu.exec(QCursor::pos()); - - if (selection != nullptr) + if (_caller == PRAGA_caller) { - std::string lapseRateCode = getLapseRateCodeName(_lapseRateCode); - if (selection == openMeteoWidget) - { - emit newStationClicked(_id, _name, _dataset, _altitude, lapseRateCode, isGrid); - } - else if (selection == appendMeteoWidget) - { - emit appendStationClicked(_id, _name, _dataset, _altitude, lapseRateCode, isGrid); - } - else if (selection == openPointStatisticsWidget) - { - emit newPointStatisticsClicked(_id, isGrid); - } - else if (selection == openHomogeneityWidget) - { - emit newHomogeneityTestClicked(_id); - } - else if (selection == openSynchronicityWidget) - { - emit newSynchronicityTestClicked(_id); - } - else if (selection == setSynchronicityReferencePoint) - { - emit setSynchronicityReferenceClicked(_id); - } - else if (selection == actionOrogCode_primary) - { - emit changeOrogCodeClicked(_id, 0); - } - else if (selection == actionOrogCode_secondary) - { - emit changeOrogCodeClicked(_id, 1); - } - else if (selection == actionOrogCode_supplemental) + QMenu menu; + QAction *openMeteoWidget = menu.addAction("Open a new meteo widget"); + QAction *appendMeteoWidget = menu.addAction("Append to the lastest meteo widget"); + menu.addSeparator(); + QAction *openPointStatisticsWidget = menu.addAction("Open point statistics widget"); + QAction *openHomogeneityWidget = menu.addAction("Open homogeneity test widget"); + menu.addSeparator(); + QAction *openSynchronicityWidget = menu.addAction("Open synchronicity test widget"); + QAction *setSynchronicityReferencePoint = menu.addAction("Set as synchronicity reference point"); + menu.addSeparator(); + QAction *actionMarkPoint = menu.addAction( "Mark point" ); + QAction *actionUnmarkPoint = menu.addAction( "Unmark point" ); + menu.addSeparator(); + QMenu *orogCodeSubMenu; + orogCodeSubMenu = menu.addMenu("Orog code"); + QAction *actionOrogCode_primary = orogCodeSubMenu->addAction( "Set as primary station" ); + QAction *actionOrogCode_secondary = orogCodeSubMenu->addAction( "Set as secondary station" ); + QAction *actionOrogCode_supplemental = orogCodeSubMenu->addAction( "Set as supplemental station" ); + + QAction *selection = menu.exec(QCursor::pos()); + + if (selection != nullptr) { - emit changeOrogCodeClicked(_id, 2); + bool isGrid = false; + std::string lapseRateCode = getLapseRateCodeName(_lapseRateCode); + if (selection == openMeteoWidget) + { + emit newStationClicked(_id, _name, _dataset, _altitude, lapseRateCode, isGrid); + } + else if (selection == appendMeteoWidget) + { + emit appendStationClicked(_id, _name, _dataset, _altitude, lapseRateCode, isGrid); + } + else if (selection == openPointStatisticsWidget) + { + emit newPointStatisticsClicked(_id, isGrid); + } + else if (selection == openHomogeneityWidget) + { + emit newHomogeneityTestClicked(_id); + } + else if (selection == openSynchronicityWidget) + { + emit newSynchronicityTestClicked(_id); + } + else if (selection == setSynchronicityReferencePoint) + { + emit setSynchronicityReferenceClicked(_id); + } + else if (selection == actionOrogCode_primary) + { + emit changeOrogCodeClicked(_id, 0); + } + else if (selection == actionOrogCode_secondary) + { + emit changeOrogCodeClicked(_id, 1); + } + else if (selection == actionOrogCode_supplemental) + { + emit changeOrogCodeClicked(_id, 2); + } + else if (selection == actionMarkPoint) + { + emit markPoint(_id); + } + else if (selection == actionUnmarkPoint) + { + emit unmarkPoint(_id); + } } - else if (selection == actionMarkPoint) - { - emit markPoint(_id); - } - else if (selection == actionUnmarkPoint) + } + else + { + // Other Software + QMenu menu; + QAction *openMeteoWidget = menu.addAction("Open a new meteo widget"); + QAction *appendMeteoWidget = menu.addAction("Append to the lastest meteo widget"); + menu.addSeparator(); + + QAction *selection = menu.exec(QCursor::pos()); + + if (selection != nullptr) { - emit unmarkPoint(_id); + bool isGrid = false; + std::string lapseRateCode = getLapseRateCodeName(_lapseRateCode); + if (selection == openMeteoWidget) + { + emit newStationClicked(_id, _name, _dataset, _altitude, lapseRateCode, isGrid); + } + else if (selection == appendMeteoWidget) + { + emit appendStationClicked(_id, _name, _dataset, _altitude, lapseRateCode, isGrid); + } } } } diff --git a/graphics/stationMarker.h b/graphics/stationMarker.h index 84171b4f..c98841de 100644 --- a/graphics/stationMarker.h +++ b/graphics/stationMarker.h @@ -5,36 +5,58 @@ #include "CircleObject.h" #include "MapGraphicsView.h" #include "quality.h" + #include "meteo.h" class Crit3DMeteoPoint; + enum callerSoftware{PRAGA_caller, CRITERIA3D_caller, other_caller}; + class StationMarker : public CircleObject { Q_OBJECT public: explicit StationMarker(qreal radius, bool sizeIsZoomInvariant, QColor fillColor, MapGraphicsObject *parent = nullptr); - void setId(std::string id); + void setToolTip(); - std::string id() const; - void setName(const std::string &name); - void setDataset(const std::string &dataset); - void setAltitude(double altitude); - void setLapseRateCode(lapseRateCodeType code); - void setMunicipality(const std::string &municipality); - void setQuality(const quality::qualityType &quality); - bool active() const; - void setActive(bool active); + + void setId(std::string id) { _id = id; } + std::string id() const { return _id; } + + bool active() const { return _active; } + void setActive(bool active) { _active = active; } + + void setName(const std::string &name) { _name = name; } + + void setDataset(const std::string &dataset) { _dataset = dataset; } + + void setAltitude(double altitude) { _altitude = altitude; } + + void setCallerSoftware(callerSoftware caller) + { _caller = caller;} + + void setLapseRateCode(lapseRateCodeType code) + { _lapseRateCode = code; } + + void setMunicipality(const std::string &municipality) + { _municipality = municipality; } + + void setQuality(const quality::qualityType &quality) + { _quality = quality; } private: std::string _id; std::string _name; std::string _dataset; - double _altitude; - lapseRateCodeType _lapseRateCode; std::string _municipality; + + double _altitude; float _currentValue; + + lapseRateCodeType _lapseRateCode; quality::qualityType _quality; + callerSoftware _caller; + bool _active; protected: diff --git a/meteoWidget/dialogMeteoTable.cpp b/meteoWidget/dialogMeteoTable.cpp index cfc30f94..7bafccb0 100644 --- a/meteoWidget/dialogMeteoTable.cpp +++ b/meteoWidget/dialogMeteoTable.cpp @@ -31,7 +31,6 @@ DialogMeteoTable::DialogMeteoTable(Crit3DMeteoSettings *meteoSettings_, QVector< QVBoxLayout* mainLayout = new QVBoxLayout; this->resize(800, 600); - meteoTable = new MeteoTable(); mainLayout->addWidget(meteoTable); diff --git a/meteoWidget/meteoWidget.cpp b/meteoWidget/meteoWidget.cpp index 079031f4..20e0e43a 100644 --- a/meteoWidget/meteoWidget.cpp +++ b/meteoWidget/meteoWidget.cpp @@ -1,24 +1,29 @@ /*! - CRITERIA3D - \copyright 2016 Fausto Tomei, Gabriele Antolini, Laura Costantini - Alberto Pistocchi, Marco Bittelli, Antonio Volta - You should have received a copy of the GNU General Public License - along with Nome-Programma. If not, see . + \file meteoWidget.cpp + + \abstract this widget displays hourly or daily weather data sets + + \copyright This file is part of CRITERIA3D. - CRITERIA3D has been developed under contract issued by A.R.P.A. Emilia-Romagna + CRITERIA3D has been developed by ARPAE Emilia-Romagna. + CRITERIA3D is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + CRITERIA3D 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 Lesser General Public License for more details. - You should have received a copy of the /NU Lesser General Public License + + You should have received a copy of the GNU Lesser General Public License along with CRITERIA3D. If not, see . - contacts: - fausto.tomei@gmail.com - ftomei@arpae.it + + \authors + Laura Costantini + Fausto Tomei ftomei@arpae.it + Gabriele Antolini gantolini@arpae.it */ @@ -117,7 +122,7 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe currentVariables.clear(); QTextStream in(&fileDefaultGraph); in.readLine(); //skip first line - while (!in.atEnd()) + while (! in.atEnd()) { QString line = in.readLine(); QList items = line.split(","); @@ -198,6 +203,7 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe hourlyVar = hourlyVar+1; } } + if (currentVariables.isEmpty() || (dailyVar != 0 && hourlyVar != 0)) { QMessageBox::information(nullptr, "Warning", "Wrong variables in Crit3DPlotDefault.csv"); @@ -415,6 +421,32 @@ Crit3DMeteoWidget::~Crit3DMeteoWidget() } +void Crit3DMeteoWidget::setCurrentFrequency(frequencyType frequency) +{ + currentFreq = frequency; + + // update gui + if (currentFreq == daily || currentFreq == noFrequency) + { + dailyButton->setEnabled(false); + hourlyButton->setEnabled(true); + monthlyButton->setEnabled(true); + } + else if (currentFreq == hourly) + { + hourlyButton->setEnabled(false); + dailyButton->setEnabled(true); + monthlyButton->setEnabled(true); + } + else if (currentFreq == monthly) + { + monthlyButton->setEnabled(false); + dailyButton->setEnabled(true); + hourlyButton->setEnabled(true); + } +} + + void Crit3DMeteoWidget::setDailyRange(QDate firstDate, QDate lastDate) { firstDailyDate = firstDate; diff --git a/meteoWidget/meteoWidget.h b/meteoWidget/meteoWidget.h index 447bc5c8..2186dfea 100644 --- a/meteoWidget/meteoWidget.h +++ b/meteoWidget/meteoWidget.h @@ -24,6 +24,8 @@ bool getIsEnsemble() { return isEnsemble; } void setNrMembers(int value) { nrMembers = value; } + void setCurrentFrequency(frequencyType frequency); + void setDailyRange(QDate firstDate, QDate lastDate); void setHourlyRange(QDate firstDate, QDate lastDate); void setMonthlyRange(QDate firstDate, QDate lastDate); diff --git a/project/project.cpp b/project/project.cpp index d21de05d..695b3e12 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -3388,7 +3388,7 @@ void Project::showMeteoWidgetPoint(std::string idMeteoPoint, std::string namePoi { bool isGrid = false; Crit3DMeteoWidget* meteoWidgetPoint = new Crit3DMeteoWidget(isGrid, projectPath, meteoSettings); - if (!meteoWidgetPointList.isEmpty()) + if (! meteoWidgetPointList.isEmpty()) { meteoWidgetId = meteoWidgetPointList[meteoWidgetPointList.size()-1]->getMeteoWidgetID()+1; } @@ -3396,6 +3396,7 @@ void Project::showMeteoWidgetPoint(std::string idMeteoPoint, std::string namePoi { meteoWidgetId = 0; } + meteoWidgetPoint->setMeteoWidgetID(meteoWidgetId); meteoWidgetPointList.append(meteoWidgetPoint); QObject::connect(meteoWidgetPoint, SIGNAL(closeWidgetPoint(int)), this, SLOT(deleteMeteoWidgetPoint(int))); @@ -3405,10 +3406,15 @@ void Project::showMeteoWidgetPoint(std::string idMeteoPoint, std::string namePoi if (hasDailyData) { meteoWidgetPoint->setDailyRange(firstDaily, lastDaily); + meteoWidgetPoint->setCurrentFrequency(daily); } if (hasHourlyData) { meteoWidgetPoint->setHourlyRange(firstHourly.date(), lastHourly.date()); + if (! hasDailyData) + { + meteoWidgetPoint->setCurrentFrequency(hourly); + } } meteoWidgetPoint->setCurrentDate(this->currentDate); diff --git a/soil/soil.cpp b/soil/soil.cpp index 71279893..05ef7289 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -1,5 +1,5 @@ /*! - CRITERIA3D + soil.cpp \copyright 2016 Fausto Tomei, Gabriele Antolini, Alberto Pistocchi, Marco Bittelli, Antonio Volta, Laura Costantini diff --git a/soilWidget/soilWidget.cpp b/soilWidget/soilWidget.cpp index 379c6278..be2d0735 100644 --- a/soilWidget/soilWidget.cpp +++ b/soilWidget/soilWidget.cpp @@ -1,5 +1,5 @@ /*! - CRITERIA3D + soilWidget.cpp \copyright 2016 Fausto Tomei, Gabriele Antolini, Laura Costantini Alberto Pistocchi, Marco Bittelli, Antonio Volta diff --git a/soilWidget/soilWidget.pro b/soilWidget/soilWidget.pro index 6b695bf1..497dd600 100644 --- a/soilWidget/soilWidget.pro +++ b/soilWidget/soilWidget.pro @@ -3,7 +3,6 @@ # Soil Widget library # This project is part of CRITERIA-3D distribution # -# #---------------------------------------------------- QT += widgets sql charts From e0262493f82cb84a40f046d6f69184752b835494 Mon Sep 17 00:00:00 2001 From: ftomei Date: Sun, 7 Jul 2024 19:06:39 +0200 Subject: [PATCH 121/179] fix color legend --- gis/color.cpp | 24 ++++++++++-------------- gis/color.h | 21 +++++++++++++-------- gis/gis.cpp | 2 +- graphics/colorLegend.cpp | 15 +++++++++------ graphics/mapGraphicsRasterObject.cpp | 4 ++-- graphics/mapGraphicsRasterUtm.cpp | 16 ++++++++++++---- 6 files changed, 47 insertions(+), 35 deletions(-) diff --git a/gis/color.cpp b/gis/color.cpp index 41a3b634..d83e0007 100644 --- a/gis/color.cpp +++ b/gis/color.cpp @@ -54,7 +54,8 @@ Crit3DColorScale::Crit3DColorScale() _minimum = NODATA; _maximum = NODATA; - _isRangeBlocked = false; + _isFixedRange = false; + _isHideOutliers = false; _classification = classificationMethod::EqualInterval; } @@ -179,10 +180,11 @@ bool setDTMScale(Crit3DColorScale* myScale) bool setLAIScale(Crit3DColorScale* myScale) { - myScale->initialize(3, 256); + myScale->initialize(4, 256); - myScale->keyColor[0] = Crit3DColor(200, 150, 0); /*!< ocra */ - myScale->keyColor[1] = Crit3DColor(32, 150, 32); /*!< dark green */ + myScale->keyColor[0] = Crit3DColor(200, 160, 0); /*!< ocra */ + myScale->keyColor[1] = Crit3DColor(160, 160, 0); /*!< yellow */ + myScale->keyColor[1] = Crit3DColor(32, 160, 32); /*!< dark green */ myScale->keyColor[2] = Crit3DColor(0, 255, 0); /*!< green */ return(myScale->classify()); @@ -205,19 +207,13 @@ bool setTemperatureScale(Crit3DColorScale* myScale) bool setSlopeStabilityScale(Crit3DColorScale* myScale) { - myScale->initialize(11, 220); + myScale->initialize(5, 256); myScale->keyColor[0] = Crit3DColor(128, 0, 128); /*!< violet */ myScale->keyColor[1] = Crit3DColor(255, 0, 0); /*!< red */ myScale->keyColor[2] = Crit3DColor(255, 255, 0); /*!< yellow */ - myScale->keyColor[3] = Crit3DColor(128, 196, 0); /*!< yellow/green */ - myScale->keyColor[4] = Crit3DColor(64, 196, 64); /*!< green */ - myScale->keyColor[5] = Crit3DColor(64, 196, 64); /*!< green */ - myScale->keyColor[6] = Crit3DColor(64, 196, 64); /*!< green */ - myScale->keyColor[7] = Crit3DColor(64, 196, 64); /*!< green */ - myScale->keyColor[8] = Crit3DColor(64, 196, 64); /*!< green */ - myScale->keyColor[9] = Crit3DColor(64, 196, 64); /*!< green */ - myScale->keyColor[10] = Crit3DColor(64, 196, 64); /*!< green */ + myScale->keyColor[3] = Crit3DColor(196, 196, 32); /*!< yellow/green */ + myScale->keyColor[4] = Crit3DColor(64, 196, 64); /*!< green */ return(myScale->classify()); } @@ -239,7 +235,7 @@ bool setAnomalyScale(Crit3DColorScale* myScale) bool setPrecipitationScale(Crit3DColorScale* myScale) { - myScale->initialize(6, 256); + myScale->initialize(6, 252); myScale->keyColor[0] = Crit3DColor(255, 255, 255); /*!< white */ myScale->keyColor[1] = Crit3DColor(0, 0, 255); /*!< blue */ diff --git a/gis/color.h b/gis/color.h index 57b4d125..526313e2 100644 --- a/gis/color.h +++ b/gis/color.h @@ -23,8 +23,9 @@ private: unsigned int _nrColors, _nrKeyColors; std::vector color; - float _minimum, _maximum; - bool _isRangeBlocked; + double _minimum, _maximum; + bool _isFixedRange; + bool _isHideOutliers; int _classification; public: @@ -38,18 +39,22 @@ unsigned int nrColors() { return _nrColors; } unsigned int nrKeyColors() { return _nrKeyColors; } - float minimum() { return _minimum; } - void setMinimum(float min) { _minimum = min; } + double minimum() { return _minimum; } + void setMinimum(double min) { _minimum = min; } - float maximum() { return _maximum; } - void setMaximum(float max) { _maximum = max; } + double maximum() { return _maximum; } + void setMaximum(double max) { _maximum = max; } Crit3DColor* getColor(float myValue); unsigned int getColorIndex(float myValue); bool setRange(float minimum, float maximum); - void setRangeBlocked(bool blocked) { _isRangeBlocked = blocked; } - bool isRangeBlocked() { return _isRangeBlocked; } + + void setFixedRange(bool fixedRange) { _isFixedRange = fixedRange; } + bool isFixedRange() { return _isFixedRange; } + + void setHideOutliers(bool hideOutliers) { _isHideOutliers = hideOutliers; } + bool isHideOutliers() { return _isHideOutliers; } }; bool setDefaultScale(Crit3DColorScale* myScale); diff --git a/gis/gis.cpp b/gis/gis.cpp index 799eab10..08f59524 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -628,7 +628,7 @@ namespace gis myGrid->maximum = maximum; myGrid->minimum = minimum; - if (! myGrid->colorScale->isRangeBlocked()) + if (! myGrid->colorScale->isFixedRange()) { myGrid->colorScale->setRange(minimum, maximum); } diff --git a/graphics/colorLegend.cpp b/graphics/colorLegend.cpp index ef0f42ff..f6c861ec 100644 --- a/graphics/colorLegend.cpp +++ b/graphics/colorLegend.cpp @@ -22,9 +22,12 @@ void ColorLegend::paintEvent(QPaintEvent *event) { Q_UNUSED(event) - if (this->colorScale == nullptr) return; + // check + if (this->colorScale == nullptr) + return; if (isEqual(this->colorScale->minimum(), NODATA) - || isEqual(this->colorScale->maximum(), NODATA)) return; + || isEqual(this->colorScale->maximum(), NODATA)) + return; QPainter painter(this); Crit3DColor* myColor; @@ -36,14 +39,14 @@ void ColorLegend::paintEvent(QPaintEvent *event) const int BLANK_DX = 16; int legendWidth = painter.window().width() - BLANK_DX*2; unsigned int nrStep = this->colorScale->nrColors(); - float step = (colorScale->maximum() - colorScale->minimum()) / float(nrStep); + double step = (colorScale->maximum() - colorScale->minimum()) / double(nrStep); double dx = double(legendWidth) / double(nrStep+1); unsigned int stepText = MAXVALUE(nrStep / 4, 1); QString valueStr; int nrDigits; double dblValue, shiftFatctor; - float value = this->colorScale->minimum(); + double value = this->colorScale->minimum(); for (unsigned int i = 0; i <= nrStep; i++) { dblValue = double(value); @@ -53,13 +56,13 @@ void ColorLegend::paintEvent(QPaintEvent *event) if ((i % stepText) == 0) { - if (isEqual(dblValue, 0)) + if (isEqual(dblValue, 0) || isEqual(dblValue, 1)) { nrDigits = 1; } else { - nrDigits = int(ceil(log10(abs(dblValue)))); + nrDigits = abs(ceil(log10(fabs(dblValue)))); } // negative numbers diff --git a/graphics/mapGraphicsRasterObject.cpp b/graphics/mapGraphicsRasterObject.cpp index 1ca41644..d1c16beb 100644 --- a/graphics/mapGraphicsRasterObject.cpp +++ b/graphics/mapGraphicsRasterObject.cpp @@ -1,7 +1,7 @@ /*! \file mapGraphicsRasterObject.cpp - \abstract draw raster in MapGraphics widget + \abstract draws a lat-lon raster in the MapGraphics widget This file is part of CRITERIA-3D distribution. @@ -381,7 +381,7 @@ bool RasterObject::drawRaster(gis::Crit3DRasterGrid *myRaster, QPainter* myPaint } // dynamic color scale - if (! myRaster->colorScale->isRangeBlocked()) + if (! myRaster->colorScale->isFixedRange()) { if (this->isLatLon) { diff --git a/graphics/mapGraphicsRasterUtm.cpp b/graphics/mapGraphicsRasterUtm.cpp index ca92733b..402a6d1d 100644 --- a/graphics/mapGraphicsRasterUtm.cpp +++ b/graphics/mapGraphicsRasterUtm.cpp @@ -1,7 +1,7 @@ /*! - \file mapGraphicsRasterObject.cpp + \file mapGraphicsRasterUtm.cpp - \abstract draw raster in MapGraphics widget + \abstract draws a UTM raster in the MapGraphics widget This file is part of CRITERIA-3D distribution. @@ -29,6 +29,7 @@ #include "commonConstants.h" #include "mapGraphicsRasterUtm.h" #include "basicMath.h" +#include "color.h" #include #include @@ -326,7 +327,7 @@ bool RasterUtmObject::drawRaster(QPainter* painter) } // dynamic color scale - if (! _rasterPointer->colorScale->isRangeBlocked()) + if (! _rasterPointer->colorScale->isFixedRange()) { gis::updateColorScale(_rasterPointer, rasterWindow); roundColorScale(_rasterPointer->colorScale, 4, true); @@ -362,10 +363,17 @@ bool RasterUtmObject::drawRaster(QPainter* painter) // raster value float value = _rasterPointer->value[rowCenter][colCenter]; - // skip the NODATA value + // check NODATA value (transparent) if (isEqual(value, _rasterPointer->header->flag) || isEqual(value, NODATA)) continue; + // check outliers (transparent) + if (_rasterPointer->colorScale->isHideOutliers()) + { + if (value < _rasterPointer->colorScale->minimum() || value > _rasterPointer->colorScale->maximum()) + continue; + } + // set color myColor = _rasterPointer->colorScale->getColor(value); myQColor = QColor(myColor->red, myColor->green, myColor->blue); From f6ce8d5cd0c2bcd8eee70e842c4ca05e63b2b8d2 Mon Sep 17 00:00:00 2001 From: ftomei Date: Sun, 7 Jul 2024 19:51:17 +0200 Subject: [PATCH 122/179] update colorscale --- graphics/colorLegend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphics/colorLegend.cpp b/graphics/colorLegend.cpp index f6c861ec..93c5a1fb 100644 --- a/graphics/colorLegend.cpp +++ b/graphics/colorLegend.cpp @@ -56,13 +56,13 @@ void ColorLegend::paintEvent(QPaintEvent *event) if ((i % stepText) == 0) { - if (isEqual(dblValue, 0) || isEqual(dblValue, 1)) + if (fabs(dblValue) <= 1) { nrDigits = 1; } else { - nrDigits = abs(ceil(log10(fabs(dblValue)))); + nrDigits = int(ceil(log10(fabs(dblValue)))); } // negative numbers From cddb08517426a7da00e46789b0e71fdfd1a7dcab Mon Sep 17 00:00:00 2001 From: giadasan Date: Mon, 8 Jul 2024 17:57:28 +0200 Subject: [PATCH 123/179] fix mingw issues --- interpolation/interpolation.cpp | 6 +++--- interpolation/interpolationSettings.cpp | 4 ++-- proxyWidget/localProxyWidget.cpp | 4 ++-- waterTable/importData.cpp | 2 +- waterTable/waterTable.cpp | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 4e5f930c..19cea4be 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1625,7 +1625,7 @@ bool multipleDetrendingMain(std::vector &myPoints if (otherParameters[0].size() > 2) { - for (int i = 0; i < (paramSize - 1); i++) + for (int i = 0; i < (int(paramSize) - 1); i++) otherParameters[i] = otherParameters[i+1]; otherParameters.pop_back(); } @@ -1771,7 +1771,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st } } - if (mySettings->getUseLocalDetrending() && elevationPoints.size() < mySettings->getMinPointsLocalDetrending()) + if (mySettings->getUseLocalDetrending() && int(elevationPoints.size()) < mySettings->getMinPointsLocalDetrending()) { elevationProxy->setIsSignificant(false); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); @@ -1999,7 +1999,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetUseLocalDetrending() && othersPoints.size() < mySettings->getMinPointsLocalDetrending()) + if (mySettings->getUseLocalDetrending() && int(othersPoints.size()) < mySettings->getMinPointsLocalDetrending()) { Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); for (int pos = 1; pos < proxyNr; pos++) diff --git a/interpolation/interpolationSettings.cpp b/interpolation/interpolationSettings.cpp index 2cc0a65b..92f65984 100644 --- a/interpolation/interpolationSettings.cpp +++ b/interpolation/interpolationSettings.cpp @@ -316,7 +316,7 @@ void Crit3DInterpolationSettings::setFittingFunction(const std::vector &)> > &newFittingFunction) { - for (int i = 0; i < newFittingFunction.size(); i ++) + for (int i = 0; i < int(newFittingFunction.size()); i ++) fittingFunction.push_back(newFittingFunction[i]); } @@ -482,7 +482,7 @@ Crit3DProxy* Crit3DInterpolationSettings::getProxy(unsigned pos) int Crit3DInterpolationSettings::getProxyPosFromName(TProxyVar name) { - for (int i = 0; i < getProxyNr(); i++) + for (int i = 0; i < int(getProxyNr()); i++) { if (getProxyPragaName(getProxyName(i)) == name) return i; diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 50a67dd4..f703ebca 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -538,7 +538,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) for (int m = xMin; m < xMax; m += 5) xVector.push_back(m); - for (int p = 0; p < xVector.size(); p++) + for (int p = 0; p < int(xVector.size()); p++) { point.setX(xVector[p]); point.setY(lapseRatePiecewiseThree_withSlope(xVector[p], parameters[proxyPos])); @@ -575,7 +575,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) for (int m = xMin; m < xMax; m += 5) xVector.push_back(m); - for (int p = 0; p < xVector.size(); p++) + for (int p = 0; p < int(xVector.size()); p++) { point.setX(xVector[p]); point.setY(lapseRatePiecewiseFree(xVector[p], parameters[proxyPos])); diff --git a/waterTable/importData.cpp b/waterTable/importData.cpp index 633abc47..31b242d0 100644 --- a/waterTable/importData.cpp +++ b/waterTable/importData.cpp @@ -173,7 +173,7 @@ bool loadWaterTableDepthCsv(const QString &csvFileName, std::vector &wellL QString id = items[posId].remove(QChar('"')); bool found = false; int index = NODATA; - for (int i = 0; i < wellList.size(); i++) + for (int i = 0; i < int(wellList.size()); i++) { if (wellList[i].getId() == id) { diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 01660c96..12eafbf0 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -142,7 +142,7 @@ bool WaterTable::setMeteoData(QDate myDate, float tmin, float tmax, float prec) { int index = firstMeteoDate.daysTo(myDate); - if (index < etpValues.size() && index < precValues.size()) + if (index < int(etpValues.size()) && index < int(precValues.size())) { Crit3DDate date = Crit3DDate(myDate.day(), myDate.month(), myDate.year()); etpValues[index] = dailyEtpHargreaves(tmin, tmax, date, well.getLatitude(), &meteoSettings); @@ -283,7 +283,7 @@ double WaterTable::computeCWB(QDate myDate, int nrDays) { actualDate = myDate.addDays(-shift); int index = firstMeteoDate.daysTo(actualDate); - if (index >= 0 && index < precValues.size()) + if (index >= 0 && index < int(precValues.size())) { float etp = etpValues[index]; float prec = precValues[index]; From 356692b5102085b63fc73183cc37d2ccfd6b0874 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 9 Jul 2024 13:43:41 +0200 Subject: [PATCH 124/179] fix color lai --- gis/color.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gis/color.cpp b/gis/color.cpp index d83e0007..bbcead0a 100644 --- a/gis/color.cpp +++ b/gis/color.cpp @@ -184,8 +184,8 @@ bool setLAIScale(Crit3DColorScale* myScale) myScale->keyColor[0] = Crit3DColor(200, 160, 0); /*!< ocra */ myScale->keyColor[1] = Crit3DColor(160, 160, 0); /*!< yellow */ - myScale->keyColor[1] = Crit3DColor(32, 160, 32); /*!< dark green */ - myScale->keyColor[2] = Crit3DColor(0, 255, 0); /*!< green */ + myScale->keyColor[2] = Crit3DColor(32, 160, 32); /*!< dark green */ + myScale->keyColor[3] = Crit3DColor(0, 255, 0); /*!< green */ return(myScale->classify()); } From 1d591b5adf23c96f88710649f7ceba4b7dd5236e Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 9 Jul 2024 16:32:36 +0200 Subject: [PATCH 125/179] fix assign index map --- gis/gis.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index 08f59524..a1282e57 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -1355,7 +1355,9 @@ namespace gis c = -1; float valueBoundary = rasterRef.getValueFromRowCol(row + r, col + c); - return isEqual(valueBoundary, rasterRef.header->flag); + bool isBoundary = isEqual(valueBoundary, rasterRef.header->flag); + + return isBoundary; } From b795a0bf08e06b810573f9a85126b538cc80c55b Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 9 Jul 2024 18:45:09 +0200 Subject: [PATCH 126/179] update 3D viewer --- graphics/mapGraphicsRasterObject.cpp | 10 ---------- graphics/mapGraphicsRasterObject.h | 6 ++++-- graphics/mapGraphicsRasterUtm.h | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/graphics/mapGraphicsRasterObject.cpp b/graphics/mapGraphicsRasterObject.cpp index d1c16beb..24a42877 100644 --- a/graphics/mapGraphicsRasterObject.cpp +++ b/graphics/mapGraphicsRasterObject.cpp @@ -73,16 +73,6 @@ void RasterObject::clear() } -void RasterObject::setRaster(gis::Crit3DRasterGrid* rasterPtr) -{ - rasterPointer = rasterPtr; -} - -gis::Crit3DRasterGrid* RasterObject::getRaster() -{ - return rasterPointer; -} - void RasterObject::setDrawing(bool value) { isDrawing = value; diff --git a/graphics/mapGraphicsRasterObject.h b/graphics/mapGraphicsRasterObject.h index bcfa7187..da44166f 100644 --- a/graphics/mapGraphicsRasterObject.h +++ b/graphics/mapGraphicsRasterObject.h @@ -79,8 +79,10 @@ const gis::Crit3DLatLonHeader& latLonHeader, bool isGrid_); float getRasterMaxSize(); gis::Crit3DGeoPoint* getRasterCenter(); - void setRaster(gis::Crit3DRasterGrid* rasterPtr); - gis::Crit3DRasterGrid* getRaster(); + + void setRaster(gis::Crit3DRasterGrid* rasterPtr) { rasterPointer = rasterPtr; } + gis::Crit3DRasterGrid* getRasterPointer() { return rasterPointer; } + void updateCenter(); Position getCurrentCenter(); diff --git a/graphics/mapGraphicsRasterUtm.h b/graphics/mapGraphicsRasterUtm.h index 2a67e962..ec679ef6 100644 --- a/graphics/mapGraphicsRasterUtm.h +++ b/graphics/mapGraphicsRasterUtm.h @@ -70,7 +70,7 @@ void setColorLegend(ColorLegend* colorLegendPtr) {_colorLegendPointer = colorLegendPtr;} void setRaster(gis::Crit3DRasterGrid* rasterPtr) {_rasterPointer = rasterPtr;} - gis::Crit3DRasterGrid* getRaster() {return _rasterPointer;} + gis::Crit3DRasterGrid* getRasterPointer() {return _rasterPointer;} float getValue(Position& pos); float getRasterMaxSize(); From 933f81a9f6e4747e394dd722e7f35b86444ea747 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 9 Jul 2024 19:21:12 +0200 Subject: [PATCH 127/179] update praga --- netcdfHandler/netcdfHandler.cpp | 5 ----- netcdfHandler/netcdfHandler.h | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/netcdfHandler/netcdfHandler.cpp b/netcdfHandler/netcdfHandler.cpp index 5873288c..3fa6e50a 100644 --- a/netcdfHandler/netcdfHandler.cpp +++ b/netcdfHandler/netcdfHandler.cpp @@ -1307,8 +1307,3 @@ bool NetCDFHandler::extractVariableMap(int idVar, const Crit3DTime &myTime, std: return true; } - -gis::Crit3DRasterGrid* NetCDFHandler::getRaster() -{ - return &dataGrid; -} diff --git a/netcdfHandler/netcdfHandler.h b/netcdfHandler/netcdfHandler.h index 20e7ec44..4e32e7dd 100644 --- a/netcdfHandler/netcdfHandler.h +++ b/netcdfHandler/netcdfHandler.h @@ -95,7 +95,7 @@ NetCDFVariable getVariableFromId(int idVar); NetCDFVariable getVariableFromIndex(int index); - gis::Crit3DRasterGrid* getRaster(); + gis::Crit3DRasterGrid* getRasterPointer() { return &dataGrid; } bool readProperties(std::string fileName); bool exportDataSeries(int idVar, gis::Crit3DGeoPoint geoPoint, Crit3DTime seriesFirstTime, Crit3DTime seriesLastTime, std::stringstream *buffer); From 63c3791fa11fb1c33df2dff6b04a8ffb5d56e09c Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 10 Jul 2024 17:34:54 +0200 Subject: [PATCH 128/179] fix viewer --- graphics/mapGraphicsRasterUtm.cpp | 2 +- meteo/meteo.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/graphics/mapGraphicsRasterUtm.cpp b/graphics/mapGraphicsRasterUtm.cpp index 402a6d1d..a45a602f 100644 --- a/graphics/mapGraphicsRasterUtm.cpp +++ b/graphics/mapGraphicsRasterUtm.cpp @@ -370,7 +370,7 @@ bool RasterUtmObject::drawRaster(QPainter* painter) // check outliers (transparent) if (_rasterPointer->colorScale->isHideOutliers()) { - if (value < _rasterPointer->colorScale->minimum() || value > _rasterPointer->colorScale->maximum()) + if (value <= _rasterPointer->colorScale->minimum() || value >= _rasterPointer->colorScale->maximum()) continue; } diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index 6a9b1f88..12eb0802 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -764,6 +764,9 @@ bool setColorScale(meteoVariable variable, Crit3DColorScale *colorScale) { if (colorScale == nullptr) return false; + colorScale->setFixedRange(false); + colorScale->setHideOutliers(false); + switch(variable) { case airTemperature: case dailyAirTemperatureAvg: case dailyAirTemperatureMax: @@ -786,6 +789,11 @@ bool setColorScale(meteoVariable variable, Crit3DColorScale *colorScale) case snowFall: case snowWaterEquivalent: case snowLiquidWaterContent: case snowMelt: case dailyWaterTableDepth: setPrecipitationScale(colorScale); + if (variable == snowFall || variable == snowWaterEquivalent + || variable == snowLiquidWaterContent || variable == snowMelt) + { + colorScale->setHideOutliers(true); + } break; case snowAge: setGrayScale(colorScale); From db719f96ca1f494ae03372a7e69c6e9e6a58d4bb Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 10 Jul 2024 19:51:43 +0200 Subject: [PATCH 129/179] update colorscale --- meteo/meteo.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index 12eb0802..d96851af 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -764,9 +764,6 @@ bool setColorScale(meteoVariable variable, Crit3DColorScale *colorScale) { if (colorScale == nullptr) return false; - colorScale->setFixedRange(false); - colorScale->setHideOutliers(false); - switch(variable) { case airTemperature: case dailyAirTemperatureAvg: case dailyAirTemperatureMax: From 973788e5d64da378290656fd1ebed6c5c2e2a368 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 11 Jul 2024 17:10:35 +0200 Subject: [PATCH 130/179] fix imposrt csv --- inOutDataXML/inOutDataXML.cpp | 57 ++++++++++++----------------------- inOutDataXML/inOutDataXML.h | 1 - pragaProject/pragaProject.cpp | 3 +- 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/inOutDataXML/inOutDataXML.cpp b/inOutDataXML/inOutDataXML.cpp index 214f8123..7cecf84f 100644 --- a/inOutDataXML/inOutDataXML.cpp +++ b/inOutDataXML/inOutDataXML.cpp @@ -143,7 +143,7 @@ bool InOutDataXML::parserXML(QString *myError) { if (child.toElement().text() == "") { - format_delimiter = " "; + format_delimiter = ","; } else { @@ -285,13 +285,13 @@ bool InOutDataXML::parserXML(QString *myError) VariableXML var; variable.push_back(var); child = ancestor.firstChild(); - while( !child.isNull()) + while(! child.isNull()) { myTag = child.toElement().tagName().toUpper(); if (myTag == "FIELD") { secondChild = child.firstChild(); - while( !secondChild.isNull()) + while(! secondChild.isNull()) { mySecondTag = secondChild.toElement().tagName().toUpper(); if (mySecondTag == "TYPE" || mySecondTag == "NAME") @@ -394,29 +394,6 @@ bool InOutDataXML::parserXML(QString *myError) } xmlDoc.clear(); - if (variableCode.getType().toUpper() == "FIXED") - { - for (int i = 0; i 1) - { - numVarFields = numVarFields + variable[i].nReplication; - } - else - { - numVarFields = numVarFields + 1; - } - } - } - else if (variable.size() > 0) - { - numVarFields = 1; - } - else - { - *myError = "Error in XML File: missing variables definition."; - return false; - } return true; } @@ -516,7 +493,7 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) int currentRow = 0; int nrErrors = 0; - while (!in.atEnd()) + while (! in.atEnd()) { QString line = in.readLine(); if (currentRow >= format_headerRow && !line.isEmpty()) @@ -564,9 +541,9 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) if (time.getType().toUpper() == "DAILY") { QDate myDate = parseXMLDate(line); - if (!myDate.isValid() || myDate.year() == 1800) + if (! myDate.isValid() || myDate.year() == 1800) { - errorStr = "Date not found or not valid for file: " + dataFileName; + errorStr = "Date not found or invalid in file:\n" + dataFileName; return false; } for (int i = 0; i myFields = line.split(format_delimiter); QDate myDate(1800,1,1); + if (time.getPosition() <= 0) + { + errorStr = "Wrong Time field position (the number of fields must start from 1): " + QString::number(time.getPosition()); + return false; + } + if (time.getPosition()-1 < myFields.size()) { myDate = parseXMLDate(myFields[time.getPosition()-1]); } - if (!myDate.isValid() || myDate.year() == 1800) + if (! myDate.isValid() || myDate.year() == 1800) { - errorStr = "Date not found or not valid for file: " + dataFileName; + errorStr = "Date not found or invalid in file:\n" + dataFileName; return false; } @@ -897,7 +880,7 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) { int nReplication = 0; - if (!variable[i].flagAccepted.isEmpty() && variable[i].flagField.getPosition()>0 && variable[i].flagField.getPosition()-1 < myFields.size()) + if (! variable[i].flagAccepted.isEmpty() && variable[i].flagField.getPosition()>0 && variable[i].flagField.getPosition()-1 < myFields.size()) { if (variable[i].varField.getPosition() > 0 && variable[i].varField.getPosition()-1 < myFields.size()) { @@ -980,9 +963,9 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) myDateTime = parseXMLDateTime(myFields[time.getPosition()-1]); } - if (!myDateTime.isValid() || myDateTime.date().year() == 1800) + if (! myDateTime.isValid() || myDateTime.date().year() == 1800) { - errorStr = "Date not found or not valid for file: " + dataFileName + "\n" + line; + errorStr = "Date not found or invalid in file:\n" + dataFileName + "\n" + line; return false; } diff --git a/inOutDataXML/inOutDataXML.h b/inOutDataXML/inOutDataXML.h index 9037b716..56daeb14 100644 --- a/inOutDataXML/inOutDataXML.h +++ b/inOutDataXML/inOutDataXML.h @@ -69,7 +69,6 @@ class InOutDataXML FieldXML variableCode; QList variable; QString dataFileName; - int numVarFields; }; #endif // INOUTDATAXML_H diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index 29e44e00..6c07da89 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -3458,8 +3458,9 @@ bool PragaProject::loadXMLImportData(QString fileName) } errorString = ""; - if (!inOutData->importDataMain(fileName, errorString)) + if (! inOutData->importDataMain(fileName, errorString)) { + logError(); return false; } From 461fb748eb27aa12c506183fd21f3e648162905e Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 11 Jul 2024 17:37:41 +0200 Subject: [PATCH 131/179] update import csv --- inOutDataXML/inOutDataXML.cpp | 72 +++++++++++++++++------------------ inOutDataXML/inOutDataXML.h | 22 +++++++---- pragaProject/pragaProject.cpp | 27 +++++++++---- 3 files changed, 71 insertions(+), 50 deletions(-) diff --git a/inOutDataXML/inOutDataXML.cpp b/inOutDataXML/inOutDataXML.cpp index 7cecf84f..aa06808a 100644 --- a/inOutDataXML/inOutDataXML.cpp +++ b/inOutDataXML/inOutDataXML.cpp @@ -12,7 +12,7 @@ InOutDataXML::InOutDataXML(bool isGrid, Crit3DMeteoPointsDbHandler *meteoPointsD this->xmlFileName = xmlFileName; this->meteoPointsDbHandler = meteoPointsDbHandler; this->meteoGridDbHandler = meteoGridDbHandler; - this->format_headerRow = 0; + this->nrHeaderRows = 0; } bool InOutDataXML::parseXMLFile(QDomDocument* xmlDoc, QString *errorStr) @@ -93,7 +93,7 @@ bool InOutDataXML::parserXML(QString *myError) } else if (mySecondTag == "NRCHAR" || mySecondTag == "NR_CHAR") { - fileName_nrChar = secondChild.toElement().text().toInt(); + nrFileNameChars = secondChild.toElement().text().toInt(); } secondChild = secondChild.nextSibling(); } @@ -124,20 +124,20 @@ bool InOutDataXML::parserXML(QString *myError) { if (child.toElement().text().toUpper().simplified() == "SINGLEPOINT") { - format_isSinglePoint = true; + isSinglePoint = true; } else { - format_isSinglePoint = false; + isSinglePoint = false; } } else if (myTag == "HEADER" || myTag == "HEADERROWS" || myTag == "NUMHEADERROWS") { - format_headerRow = child.toElement().text().toInt(); + nrHeaderRows = child.toElement().text().toInt(); } else if (myTag == "MISSINGVALUE" || myTag == "MISSING_VALUE" || myTag == "NODATA") { - format_missingValue = child.toElement().text().toFloat(); + missingValue = child.toElement().text().toFloat(); } else if (myTag == "DELIMITER") { @@ -422,7 +422,7 @@ bool InOutDataXML::checkPointCodeFromFileName(QString& myPointCode, QString& err { myPointCode = ""; - if (! format_isSinglePoint) + if (! isSinglePoint) { errorStr = "Not singlePoint format."; return true; @@ -476,7 +476,7 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) QString myPointCode = ""; QString previousPointCode = ""; - if (format_isSinglePoint) + if (isSinglePoint) { if (! checkPointCodeFromFileName(myPointCode, errorStr)) { @@ -496,9 +496,9 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) while (! in.atEnd()) { QString line = in.readLine(); - if (currentRow >= format_headerRow && !line.isEmpty()) + if (currentRow >= nrHeaderRows && !line.isEmpty()) { - if (!format_isSinglePoint) + if (! isSinglePoint) { // multipoint myPointCode = parseXMLPointCode(line); @@ -576,16 +576,16 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) if (myValue.toString() == "ERROR") { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; } else if (myFlag != myFlagAccepted) { - myValue = format_missingValue; + myValue = missingValue; } } // end flag if - if (myValue != format_missingValue) + if (myValue != missingValue) { // write myValue meteoVariable var = getKeyMeteoVarMeteoMap(MapDailyMeteoVarToString, variable[i].varField.getType().toStdString()); @@ -652,7 +652,7 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) if (myFlag != myFlagAccepted) { - myValue = format_missingValue; + myValue = missingValue; } else { @@ -660,12 +660,12 @@ bool InOutDataXML::importXMLDataFixed(QString& errorStr) if (myValue.toString() == "ERROR") { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; } } } - if (myValue != format_missingValue) + if (myValue != missingValue) { // write myValue meteoVariable var = getKeyMeteoVarMeteoMap(MapHourlyMeteoVarToString, variable[i].varField.getType().toStdString()); @@ -781,7 +781,7 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) QString myPointCode = ""; QString previousPointCode = ""; - if (format_isSinglePoint) + if (isSinglePoint) { if (! checkPointCodeFromFileName(myPointCode, errorStr)) { @@ -802,9 +802,9 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) { QString line = in.readLine(); - if (currentRow >= format_headerRow && !line.isEmpty()) + if (currentRow >= nrHeaderRows && !line.isEmpty()) { - if (! format_isSinglePoint) + if (! isSinglePoint) { QList myFields = line.split(format_delimiter); @@ -888,19 +888,19 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) if (myValue.toString() == "ERROR") { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; } } else { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; return false; } // check FLAG if (myFields[variable[i].flagField.getPosition()-1] != variable[i].flagAccepted) { - myValue = format_missingValue; + myValue = missingValue; } } else @@ -911,17 +911,17 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) if (myValue.toString() == "ERROR") { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; } } else { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; return false; } } - if (myValue != format_missingValue && myValue != NODATA) + if (myValue != missingValue && myValue != NODATA) { // write value meteoVariable var = getKeyMeteoVarMeteoMap(MapDailyMeteoVarToString, variable[i].varField.getType().toStdString()); @@ -987,19 +987,19 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) if (myValue.toString() == "ERROR") { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; } } else { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; return false; } // check FLAG if (myFields[variable[i].flagField.getPosition()-1] != variable[i].flagAccepted) { - myValue = format_missingValue; + myValue = missingValue; } } else @@ -1010,17 +1010,17 @@ bool InOutDataXML::importXMLDataDelimited(QString& errorStr) if (myValue.toString() == "ERROR") { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; } } else { nrErrors++; - myValue = format_missingValue; + myValue = missingValue; return false; } } - if (myValue != format_missingValue && myValue != NODATA) + if (myValue != missingValue && myValue != NODATA) { // write myValue meteoVariable var = getKeyMeteoVarMeteoMap(MapHourlyMeteoVarToString, variable[i].varField.getType().toStdString()); @@ -1155,11 +1155,11 @@ QString InOutDataXML::parseXMLPointCode(QString text) { // con questa casistica l'import funziona anche con gli xml di export che hanno il campo filename e prefissi o suffissi nel nome del file QString substring = text; - for (int i = 0; i fileName_nrChar) + if (code.length() > nrFileNameChars) { return filename; } @@ -1371,7 +1371,7 @@ int InOutDataXML::getVariableFlagFirstChar() float InOutDataXML::getFormatMissingValue() { - return format_missingValue; + return missingValue; } diff --git a/inOutDataXML/inOutDataXML.h b/inOutDataXML/inOutDataXML.h index 56daeb14..2c53e0ca 100644 --- a/inOutDataXML/inOutDataXML.h +++ b/inOutDataXML/inOutDataXML.h @@ -19,7 +19,9 @@ enum formatType{ XMLFORMATFIXED, XMLFORMATDELIMITED}; class InOutDataXML { public: - InOutDataXML(bool isGrid, Crit3DMeteoPointsDbHandler* meteoPointsDbHandler, Crit3DMeteoGridDbHandler* meteoGridDbHandler, QString xmlFileName); + InOutDataXML(bool isGrid, Crit3DMeteoPointsDbHandler* meteoPointsDbHandler, + Crit3DMeteoGridDbHandler* meteoGridDbHandler, QString xmlFileName); + bool parseXMLFile(QDomDocument* xmlDoc, QString *error); bool parserXML(QString *error); bool importDataMain(QString fileName, QString &error); @@ -50,25 +52,31 @@ class InOutDataXML private: bool isGrid; + bool isSinglePoint; + formatType format_type; + + int nrHeaderRows; + int nrFileNameChars; + float missingValue; + Crit3DMeteoPointsDbHandler* meteoPointsDbHandler; Crit3DMeteoGridDbHandler* meteoGridDbHandler; + QString xmlFileName; - bool format_isSinglePoint; - formatType format_type; - int format_headerRow; - float format_missingValue; + QString dataFileName; QString format_delimiter; QString format_decimalSeparator; QString fileName_path; QString fileName_pragaName; + QList fileName_fixedPrefix; QList fileName_fixedSuffix; - int fileName_nrChar; + FieldXML time; FieldXML pointCode; FieldXML variableCode; + QList variable; - QString dataFileName; }; #endif // INOUTDATAXML_H diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index 6c07da89..8d8febd3 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -3467,6 +3467,7 @@ bool PragaProject::loadXMLImportData(QString fileName) return true; } + bool PragaProject::loadXMLExportData(QString code, QDateTime myFirstTime, QDateTime myLastTime) { errorString = ""; @@ -3493,23 +3494,27 @@ bool PragaProject::loadXMLExportData(QString code, QDateTime myFirstTime, QDateT fixedString.insert(0, " "); } } + int variableCodeFirstChar = inOutData->getVariableCodeFirstChar(); int whiteSpaces = variableCodeFirstChar - (fixedString.length()+1); - for (int i = 0; igetVariableCodeAttribute(); - if (!attribute.isEmpty()) + if (! attribute.isEmpty()) { fixedString = fixedString + attribute; } + int timeFirstChar = inOutData->getTimeFirstChar(); whiteSpaces = timeFirstChar - (fixedString.length()+1); - for (int i = 0; igetVariableAlign(); int variableFirstChar = inOutData->getVariableFirstChar(); int variableNrChar = inOutData->getVariableNrChar(); @@ -3660,6 +3665,7 @@ bool PragaProject::loadXMLExportDataGrid(QString code, QDateTime myFirstTime, QD errorString = "Invalid filename" ; return false; } + QString variable = inOutData->getVariableExport(); meteoVariable meteoVar = getMeteoVar(variable.toStdString()); if (meteoVar == noMeteoVar) @@ -3667,39 +3673,45 @@ bool PragaProject::loadXMLExportDataGrid(QString code, QDateTime myFirstTime, QD errorString = "Unknown meteo variable: " + variable; return false; } + QString fixedString = ""; int pointCodeFirstChar = inOutData->getPointCodeFirstChar(); if (pointCodeFirstChar != NODATA) { fixedString = code; - for (int i = 0; igetVariableCodeFirstChar(); int whiteSpaces = variableCodeFirstChar - (fixedString.length()+1); - for (int i = 0; igetVariableCodeAttribute(); - if (!attribute.isEmpty()) + if (! attribute.isEmpty()) { fixedString = fixedString + attribute; } + int timeFirstChar = inOutData->getTimeFirstChar(); whiteSpaces = timeFirstChar - (fixedString.length()+1); - for (int i = 0; igetVariableAlign(); int variableFirstChar = inOutData->getVariableFirstChar(); int variableNrChar = inOutData->getVariableNrChar(); QString variableFormat = inOutData->getVariableFormat(); QChar charFormat = variableFormat[variableFormat.length()-1]; int nDecimals = variableFormat.mid(variableFormat.length()-2,1).toInt(); + if (variableAlign.isEmpty()) { variableAlign = "right"; //default @@ -3709,6 +3721,7 @@ bool PragaProject::loadXMLExportDataGrid(QString code, QDateTime myFirstTime, QD errorString = "Invalid alignment: " + variableAlign; return false; } + QString flagAccepted = inOutData->getVariableFlagAccepted(); int flagFirstChar = 0; if (!flagAccepted.isEmpty()) From dae25e712574b26cae15ae6ff0fd848588ad6b0d Mon Sep 17 00:00:00 2001 From: cate-to Date: Fri, 12 Jul 2024 16:04:30 +0200 Subject: [PATCH 132/179] changes in multiple detrending --- gis/gis.cpp | 72 ++++- gis/gis.h | 3 +- interpolation/interpolation.cpp | 364 ++++++++++++++++-------- interpolation/interpolation.h | 7 +- interpolation/interpolationConstants.h | 1 + interpolation/interpolationSettings.cpp | 71 ++++- interpolation/interpolationSettings.h | 7 +- mathFunctions/furtherMathFunctions.cpp | 313 ++++++++++---------- mathFunctions/furtherMathFunctions.h | 5 +- project/dialogInterpolation.cpp | 1 + project/interpolationCmd.cpp | 2 +- project/project.cpp | 37 ++- proxyWidget/localProxyWidget.cpp | 162 +++++------ 13 files changed, 657 insertions(+), 388 deletions(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index f73f6405..d443738f 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -287,8 +287,7 @@ namespace gis bool Crit3DRasterGrid::initializeParameters(const Crit3DRasterHeader& initHeader) { - if (!parametersCell.empty()) - parametersCell.clear(); + parametersCell.clear(); parametersCell.resize(initHeader.nrRows*initHeader.nrCols); for (int i = 0; i < int(parametersCell.size()); i++) { @@ -517,7 +516,74 @@ namespace gis return true; } - std::vector> Crit3DRasterGrid::prepareParameters(int row, int col, unsigned int activeProxyNr) + std::vector> Crit3DRasterGrid::prepareParameters(int row, int col, std::vector activeList) + { + std::vector> tempProxyVector; + tempProxyVector.clear(); + tempProxyVector.resize(activeList.size()); + int l, m, k, p; + l = 0; + m = 0; + std::vector avg; + int counter, index; + bool findFirst = 0; + + if (isOutOfGrid(row, col)) + return tempProxyVector; + + for (unsigned int i = 0; i < activeList.size(); i++) + { + findFirst = 0; + if (activeList[i]) + { + //look for the first cell that has data for that proxy. if there isn't any, return empty vector + for (l = row-1; l < row+2; l++) + { + for (m = col-1; m < col+2; m++) + { + index = l * header->nrCols + m; + if (index >= 0 && index < int(parametersCell.size()) && (parametersCell[index].fittingParameters.size() > i && !parametersCell[index].fittingParameters[i].empty()) && (l != row || m !=col)) { + findFirst = 1; + } + if (findFirst==1) break; + } + if (findFirst==1) break; + } + + if (findFirst == 0) + continue; + + //you're on a specific proxy rn. cycle through the cells, calculate the avg + avg.clear(); + avg.resize(parametersCell[index].fittingParameters[i].size()); + counter = 0; + + for (k = l; k < row+2; k++) + { + for (p = m; p < col+2; p++) + { + index = k * header->nrCols + p; + if (index >= 0 && index < int(parametersCell.size()) && parametersCell[index].fittingParameters.size() > i && !parametersCell[index].fittingParameters[i].empty()) { + for (unsigned int o = 0; o < avg.size(); o++) + { + avg[o] += parametersCell[index].fittingParameters[i][o]; + + } + counter++; + } + } + } + for (unsigned int o = 0; o < avg.size(); o++) + avg[o] /= counter; + + tempProxyVector[i] = avg; + } + } + + return tempProxyVector; + } + + std::vector> Crit3DRasterGrid::prepareParametersOld(int row, int col, unsigned int activeProxyNr) { std::vector> tempProxyVector; std::vector tempParVector; diff --git a/gis/gis.h b/gis/gis.h index 221e693d..6a25e4ca 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -191,7 +191,8 @@ float getValueFromXY(double x, double y) const; std::vector> getParametersFromRowCol(int row, int col); bool setParametersForRowCol(int row, int col, std::vector> parameters); - std::vector> prepareParameters(int row, int col, unsigned int activeProxyNr); + std::vector> prepareParameters(int row, int col, std::vector activeList); + std::vector> prepareParametersOld(int row, int col, unsigned int activeProxyNr); Crit3DTime getMapTime() const; void setMapTime(const Crit3DTime &value); diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 4e5f930c..99a34930 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1039,7 +1039,7 @@ void localSelection(vector &inputPoints, vector < unsigned int i; unsigned int nrPrimaries = 0; - float maxDistance = 0; + int maxDistance = 0; float maxHeightDelta = 0; while (nrValid < minPoints || (mySettings.getUseLapseRateCode() && nrPrimaries < minPoints)) { @@ -1051,7 +1051,7 @@ void localSelection(vector &inputPoints, vector < selectedPoints.push_back(inputPoints[i]); nrValid++; if (inputPoints[i].distance > maxDistance) - maxDistance = inputPoints[i].distance; + maxDistance = int(inputPoints[i].distance); if (checkLapseRateCode(inputPoints[i].lapseRateCode, mySettings.getUseLapseRateCode(), true)) nrPrimaries++; @@ -1067,11 +1067,13 @@ void localSelection(vector &inputPoints, vector < if (maxDistance != 0 && maxHeightDelta != 0) for (i=0; i< selectedPoints.size(); i++) { - selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (maxDistance*maxDistance), EPSILON); + //selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (std::pow(maxDistance, 16.0/15.0)), EPSILON); + selectedPoints[i].regressionWeight = MAXVALUE(std::exp(-std::pow(selectedPoints[i].distance/(0.8*maxDistance),3.0)),EPSILON); + //selectedPoints[i].regressionWeight = 1; selectedPoints[i].heightWeight = 1./((2./maxHeightDelta)*selectedPoints[i].point->z+1); //selectedPoints[i].heightWeight = 1; } - mySettings.setLocalRadius(maxDistance); + mySettings.setLocalRadius(float(maxDistance)); } @@ -1201,8 +1203,17 @@ float retrend(meteoVariable myVar, vector myProxyValues, Crit3DInterpola if (getActiveProxyValues(myCombination, myProxyValues, activeProxyValues)) { - std::vector&)>> myFunc = mySettings->getFittingFunction(); + std::vector&)>> fullFunc = mySettings->getFittingFunction(); std::vector > fittingParameters = mySettings->getFittingParameters(); + removeEmptyFittingParameters(fittingParameters); + + std::vector&)>> myFunc; + + for (const auto& function : fullFunc) { + if (function) { + myFunc.push_back(function); + } + } if (myFunc.size() > 0 && fittingParameters.size() > 0) retrendValue = float(functionSum(myFunc, activeProxyValues, fittingParameters)); @@ -1348,6 +1359,51 @@ bool proxyValidity(std::vector &myPoints, int pro return true; } +bool proxyValidityWeighted(std::vector &myPoints, int proxyPos, float stdDevThreshold, double &avg, double &stdDev) +{ + std::vector proxyValues; + const int MIN_NR = 10; + + std::vector data, weights; + data.resize(myPoints.size()); + weights.resize(myPoints.size()); + + for (int i = 0; i < myPoints.size(); i++) + { + data[i] = myPoints[i].getProxyValue(proxyPos); + weights[i] = myPoints[i].regressionWeight; + } + + + if (data.size() <= 0) { + // Handle the case when there is no data or weights + return 0.0; + } + + double sum_weights = 0.0; + double sum_weighted_data = 0.0; + double sum_squared_weighted_data = 0.0; + + // Calculate the necessary sums for weighted variance calculation + for (int i = 0; i < int(data.size()); i++) + { + sum_weights += weights[i]; + sum_weighted_data += data[i] * weights[i]; + sum_squared_weighted_data += data[i] * data[i] * weights[i]; + } + + // Calculate the weighted variance + double weighted_mean = sum_weighted_data / sum_weights; + double variance = (sum_squared_weighted_data / sum_weights) - (weighted_mean * weighted_mean); + + stdDev = sqrt(variance); + + if (stdDevThreshold != NODATA) + return (stdDev > stdDevThreshold); + else + return true; +} + bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings) { if (mySettings->getMinMaxTemperature().empty()) @@ -1360,31 +1416,57 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati { double min = mySettings->getMinMaxTemperature()[0]; double max = mySettings->getMinMaxTemperature()[1]; - std::vector tempParam; - if (mySettings->getChosenElevationFunction() == piecewiseTwo) - { - mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); - tempParam = {-200, min-2, 0, -0.01, 5000, max+2, 0.01, 0.0015}; - } - else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) - { - mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); - tempParam = {-200, min-2, 100, 0, -0.01, -0.01, 5000, max+2, 1000, 0.007, 0.0015, 0.0015}; - } - else if (mySettings->getChosenElevationFunction() == piecewiseThree) + + if (mySettings->getChosenElevationFunction() == mySettings->getProxy(i)->getFittingFunctionName()) { - mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - tempParam = {-200, min-2, 100, 0, -0.01, 5000, max+2, 1000, 0.007, 0.0015}; + std::vector tempParam; + tempParam = mySettings->getProxy(i)->getFittingParametersRange(); + if (!tempParam.empty()) + { + if (mySettings->getChosenElevationFunction() == piecewiseTwo) + { + tempParam[1] = min-2; + tempParam[5] = max+2; + } + else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) + { + tempParam[1] = min-2; + tempParam[7] = max+2; + } + else if (mySettings->getChosenElevationFunction() == piecewiseThree) + { + tempParam[1] = min-2; + tempParam[6] = max+2; + } + mySettings->getProxy(i)->setFittingParametersRange(tempParam); + } } - else if (mySettings->getChosenElevationFunction() == freiFree) + else { - mySettings->getProxy(i)->setFittingFunctionName(freiFree); - tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 5000, 1000, 0.006}; + std::vector tempParam; + if (mySettings->getChosenElevationFunction() == piecewiseTwo) + { + mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); + tempParam = {-200, min-2, 0.002, -0.01, 5000, max+2, 0.01, 0.0015}; + } + else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) + { + mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); + tempParam = {-200, min-2, 300, 0.002, -0.01, -0.01, 5000, max+2, 1000, 0.007, 0.0015, 0.0015}; + } + else if (mySettings->getChosenElevationFunction() == piecewiseThree) + { + mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); + tempParam = {-200, min-2, 300, 0.002, -0.01, 5000, max+2, 1000, 0.007, 0.0015}; + } + else if (mySettings->getChosenElevationFunction() == freiFree) + { + mySettings->getProxy(i)->setFittingFunctionName(freiFree); + tempParam = {min, 0, -4, -200, 0.1, 0.002, max+10, 0.006, 4, 5000, 1000, 0.006}; + } + mySettings->getProxy(i)->setFittingParametersRange(tempParam); } - mySettings->getProxy(i)->setFittingParametersRange(tempParam); } - else - mySettings->getProxy(i)->setFittingFunctionName(linear); } return true; } @@ -1395,8 +1477,15 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 std::vector > ¶mDelta, std::vector > ¶mFirstGuess, std::string &errorStr) { - bool isPreviousParam = false; - unsigned int elevationPos = NODATA; + + int elevationPos = NODATA; + std::vector> tempFirstGuess = paramFirstGuess; + unsigned int nrProxy = mySettings->getSelectedCombination().getProxySize(); + paramFirstGuess.clear(); + paramMin.resize(nrProxy); + paramMax.resize(nrProxy); + paramDelta.resize(nrProxy); + paramFirstGuess.resize(nrProxy); for (unsigned int i = 0; i < mySettings->getSelectedCombination().getProxySize(); i++) { @@ -1404,28 +1493,6 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 elevationPos = i; } - if (myCombination.getProxySize() > 0) - { - if (myCombination.isProxyActive(elevationPos)) - { - if (paramFirstGuess.size() > 0) - { - if (paramFirstGuess[0].size() > 0) - isPreviousParam = true; - } - } - else - { - if (paramFirstGuess.size() > 0) //no? TODO - isPreviousParam = true; - } - } - else - { - errorStr = "no proxy selected."; - return false; - } - const double RATIO_DELTA = 1000; for (unsigned i=0; i < myCombination.getProxySize(); i++) @@ -1434,13 +1501,13 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 if (getProxyPragaName(mySettings->getProxy(i)->getName()) == proxyHeight) { if (mySettings->getChosenElevationFunction() == piecewiseTwo) - myFunc.push_back(lapseRatePiecewise_two); + myFunc[i] = lapseRatePiecewise_two; else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) - myFunc.push_back(lapseRatePiecewiseFree); + myFunc[i] = lapseRatePiecewiseFree; else if (mySettings->getChosenElevationFunction() == piecewiseThree) - myFunc.push_back(lapseRatePiecewiseThree_withSlope); + myFunc[i] = lapseRatePiecewiseThree_withSlope; else if (mySettings->getChosenElevationFunction() == freiFree) - myFunc.push_back(lapseRateFreiFree); + myFunc[i] = lapseRateFreiFree; else { errorStr = "Missing or wrong fitting function for proxy: " + mySettings->getProxy(i)->getName(); @@ -1448,7 +1515,7 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 } } else - myFunc.push_back(functionLinear_intercept); + myFunc[i] = functionLinear_intercept; std::vector myParam = mySettings->getProxy(i)->getFittingParametersRange(); unsigned int nrParam = unsigned(myParam.size() / 2); @@ -1475,11 +1542,13 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 proxyParamFirstGuess.push_back((max_ + min_) / 2); } - paramMin.push_back(proxyParamMin); - paramMax.push_back(proxyParamMax); - paramDelta.push_back(proxyParamDelta); - if (!isPreviousParam) - paramFirstGuess.push_back(proxyParamFirstGuess); + paramMin[i] = proxyParamMin; + paramMax[i] = proxyParamMax; + paramDelta[i] = proxyParamDelta; + if (tempFirstGuess[i].empty()) + paramFirstGuess[i] = proxyParamFirstGuess; + else + paramFirstGuess[i] = tempFirstGuess[i]; } return myFunc.size() > 0; @@ -1604,52 +1673,41 @@ std::vector getfittingParameters(Crit3DProxyCombination myCombination, bool multipleDetrendingMain(std::vector &myPoints, Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr) { - std::vector> otherParameters = mySettings->getFittingParameters(); - std::vector > elevationParameters = mySettings->getFittingParameters(); - size_t paramSize = mySettings->getFittingParameters().size(); - mySettings->clearFitting(); - int elevationPos = NODATA; - - for (unsigned int pos=0; pos < mySettings->getCurrentCombination().getProxySize(); pos++) + int elevationPos = NODATA; + for (unsigned int pos=0; pos < mySettings->getCurrentCombination().getProxySize(); pos++) { - if (getProxyPragaName(mySettings->getProxy(pos)->getName()) == proxyHeight) + if (getProxyPragaName(mySettings->getProxy(pos)->getName()) == proxyHeight) elevationPos = pos; } + std::vector> parameters = mySettings->getFittingParameters(); + mySettings->clearFitting(); + if (mySettings->getCurrentCombination().isProxyActive(elevationPos)) { - if (elevationParameters.size() > 0) //forse meglio fare vettore con dimensione = nrProxy (attivi) - { - while (elevationParameters.back().size() < 4) - elevationParameters.pop_back(); - - if (otherParameters[0].size() > 2) - { - for (int i = 0; i < (paramSize - 1); i++) - otherParameters[i] = otherParameters[i+1]; - otherParameters.pop_back(); - } - } - Crit3DProxyCombination elevationCombination; elevationCombination.resetCombination(mySettings->getSelectedCombination().getProxySize()); elevationCombination.setProxyActive(elevationPos, true); - if (!multipleDetrendingElevation(elevationCombination, elevationParameters, myPoints, mySettings, myVar, errorStr)) + if (parameters.empty()) { + parameters.resize(elevationPos + 1); + } + + if (!multipleDetrendingElevation(elevationCombination, parameters[elevationPos], myPoints, mySettings, myVar, errorStr)) return false; } Crit3DProxyCombination othersCombination = mySettings->getSelectedCombination(); othersCombination.setProxyActive(elevationPos,false); - if (!multipleDetrending(othersCombination, otherParameters, myPoints, mySettings, myVar, errorStr)) + if (!multipleDetrending(othersCombination, parameters, myPoints, mySettings, myVar, errorStr)) return false; return true; } -bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, std::vector> parameters, std::vector &myPoints, +bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, std::vector elevationParameters, std::vector &myPoints, Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr) { @@ -1657,10 +1715,8 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st int elevationPos = NODATA; for (unsigned int pos = 0; pos < elevationCombination.getProxySize(); pos++) - { if (elevationCombination.isProxyActive(pos)) elevationPos = pos; - } if (elevationPos == NODATA) return true; @@ -1684,7 +1740,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st unsigned validNr; validNr = 0; - if (proxyValidity(elevationPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + if (proxyValidityWeighted(elevationPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) { elevationCombination.setProxySignificant(elevationPos, true); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); @@ -1708,36 +1764,38 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st bool isValid; float proxyValue; it = myPoints.begin(); + vector::iterator elevationIt = elevationPoints.begin(); while (it != myPoints.end()) { isValid = true; proxyValue = it->getProxyValue(elevationPos); + \ if (proxyValue == NODATA) - isValid = false; + isValid = false; if (! isValid) it = myPoints.erase(it); else it++; - } - it = elevationPoints.begin(); - while (it != elevationPoints.end()) - { isValid = true; - proxyValue = it->getProxyValue(elevationPos); - if (proxyValue == NODATA) - isValid = false; + if (elevationIt != elevationPoints.end()) + { + proxyValue = elevationIt->getProxyValue(elevationPos); + + if (proxyValue == NODATA) + isValid = false; + if (!isValid) + elevationIt = elevationPoints.erase(elevationIt); + else + elevationIt++; + } - if (! isValid) - it = elevationPoints.erase(it); - else - it++; } // proxy spatial variability (2nd step) - if (proxyValidity(elevationPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) + if (proxyValidityWeighted(elevationPoints, elevationPos, elevationProxy->getStdDevThreshold(), avg, stdDev)) { elevationCombination.setProxySignificant(elevationPos, true); Crit3DProxyCombination myCombination = mySettings->getSelectedCombination(); @@ -1784,12 +1842,15 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st std::vector > parametersMin; std::vector > parametersMax; std::vector > parametersDelta; - //std::vector > parameters; - std::vector&)>> myFunc; + std::vector > parameters; + parameters.resize(mySettings->getCurrentCombination().getProxySize()); + std::vector&)>> myFunc(mySettings->getCurrentCombination().getProxySize(), nullptr); - unsigned int nrMaxStep = 100; - if (parameters.empty()) + unsigned int nrMaxStep = 200; + if (elevationParameters.empty()) nrMaxStep *= 10; + else + parameters[elevationPos] = elevationParameters; if (! setAllFittingParameters_noRange(elevationCombination, mySettings, myFunc, parametersMin, parametersMax, parametersDelta, parameters, errorStr)) @@ -1797,9 +1858,8 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st errorStr = "couldn't prepare the fitting parameters for proxy: elevation."; return false; } - int pos = 0; - auto func = myFunc[pos].target&)>(); + auto func = myFunc[elevationPos].target&)>(); if (!func) { @@ -1808,12 +1868,28 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st } // multiple non linear fitting - interpolation::bestFittingMarquardt_nDimension_singleFunction(*func, nrMaxStep, 4, parametersMin[pos], parametersMax[pos], parameters[pos], parametersDelta[pos], + interpolation::bestFittingMarquardt_nDimension_singleFunction(*func, nrMaxStep, 4, parametersMin[elevationPos], parametersMax[elevationPos], parameters[elevationPos], parametersDelta[elevationPos], 100, 0.005, 0.002, predictors, predictands, weights); - mySettings->setFittingFunction(myFunc); - mySettings->setFittingParametersElevation(parameters[elevationPos]); + mySettings->setSingleFittingFunction(myFunc[elevationPos], elevationPos); + mySettings->setSingleFittingParameters(parameters[elevationPos], elevationPos); + + + if (mySettings->getProxy(elevationPos)->getFittingFunctionName() == piecewiseTwo) + { + myFunc[elevationPos] = detrendingLapseRatePiecewise_two; + mySettings->setSingleFittingFunction(detrendingLapseRatePiecewise_two, elevationPos); + } else if (mySettings->getProxy(elevationPos)->getFittingFunctionName() == piecewiseThreeFree) + { + myFunc[elevationPos] = detrendingLapseRatePiecewiseFree; + mySettings->setSingleFittingFunction(detrendingLapseRatePiecewiseFree, elevationPos); + } else if (mySettings->getProxy(elevationPos)->getFittingFunctionName() == piecewiseThree) + { + myFunc[elevationPos] = detrendingLapseRatePiecewiseThree_withSlope; + mySettings->setSingleFittingFunction(detrendingLapseRatePiecewiseThree_withSlope, elevationPos); + } + func = myFunc[elevationPos].target&)>();; // detrending float detrendValue; @@ -1833,6 +1909,13 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetCurrentCombination().getProxySize(); tempPos++) + { + if (getProxyPragaName(mySettings->getProxy(tempPos)->getName()) == proxyHeight) + elevationPos = tempPos; + } + // verify predictors number unsigned nrPredictors = 0; std::vector proxyIndex; @@ -1871,7 +1954,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetProxy(pos)->getStdDevThreshold(), avg, stdDev)) + if (proxyValidityWeighted(othersPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) { othersCombination.setProxySignificant(pos, true); Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); @@ -1888,7 +1971,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorsetCurrentCombination(myCombination); mySettings->getProxy(pos)->setIsSignificant(false); - parameters.clear(); + } } } @@ -1954,7 +2037,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetProxy(pos)->getStdDevThreshold(), avg, stdDev)) + if (proxyValidityWeighted(othersPoints, pos, mySettings->getProxy(pos)->getStdDevThreshold(), avg, stdDev)) { othersCombination.setProxySignificant(pos, true); Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); @@ -1971,7 +2054,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorsetCurrentCombination(myCombination); mySettings->getProxy(pos)->setIsSignificant(false); - parameters.clear(); + } } } @@ -2002,11 +2085,14 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorgetUseLocalDetrending() && othersPoints.size() < mySettings->getMinPointsLocalDetrending()) { Crit3DProxyCombination myCombination = mySettings->getCurrentCombination(); - for (int pos = 1; pos < proxyNr; pos++) + for (int pos = 0; pos < proxyNr; pos++) { - myCombination.setProxyActive(pos, false); - myCombination.setProxySignificant(pos, false); - mySettings->getProxy(pos)->setIsSignificant(false); + if (pos != elevationPos) + { + myCombination.setProxyActive(pos, false); + myCombination.setProxySignificant(pos, false); + mySettings->getProxy(pos)->setIsSignificant(false); + } } mySettings->setCurrentCombination(myCombination); return true; @@ -2016,7 +2102,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector> parametersMax; std::vector > parametersDelta; //std::vector > parameters; - std::vector&)>> myFunc; + std::vector&)>> myFunc(mySettings->getCurrentCombination().getProxySize(), nullptr); unsigned int nrMaxStep = 100; if (parameters.empty()) @@ -2026,12 +2112,40 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector&)>> fullFunc = myFunc; + myFunc.clear(); + + for (const auto& function : fullFunc) { + if (function) { + myFunc.push_back(function); + } + } + + removeEmptyFittingParameters(parameters); + removeEmptyFittingParameters(parametersMin); + removeEmptyFittingParameters(parametersMax); + removeEmptyFittingParameters(parametersDelta); + // multiple non linear fitting interpolation::bestFittingMarquardt_nDimension(&functionSum, myFunc, nrMaxStep, 4, parametersMin, parametersMax, parameters, parametersDelta, - 100, 0.005, 0.002, predictors, predictands, weights); + 100, 0.005, 0.002, predictors, predictands, weights, elevationPos); + + + int k = 0; + for (unsigned int i = 0; i < othersCombination.getProxySize(); i++) + { + if (i != elevationPos && othersCombination.isProxyActive(i) && othersCombination.isProxySignificant(i)) + { + if (k < parameters.size()) + { + mySettings->setSingleFittingParameters(parameters[k], i); + mySettings->setSingleFittingFunction(functionLinear, i); + } + k++; + myFunc[i] = functionLinear; + } + } - mySettings->addFittingFunction(myFunc); - mySettings->addFittingParameters(parameters); std::vector proxyValues; @@ -2265,6 +2379,16 @@ bool getActiveProxyValues(Crit3DProxyCombination myCombination, const std::vecto return (activeProxyValues.size() > 0 && isComplete); } +void removeEmptyFittingParameters(std::vector > &fittingParameters) +{ + auto newEnd = std::remove_if(fittingParameters.begin(), fittingParameters.end(), [](const std::vector& v) { + return v.empty(); + }); + + fittingParameters.erase(newEnd, fittingParameters.end()); + + return; +} bool getProxyValuesXY(float x, float y, Crit3DInterpolationSettings* mySettings, std::vector &myValues) { diff --git a/interpolation/interpolation.h b/interpolation/interpolation.h index f301dfc5..013a12f0 100644 --- a/interpolation/interpolation.h +++ b/interpolation/interpolation.h @@ -63,6 +63,8 @@ bool getActiveProxyValues(Crit3DProxyCombination myCombination, const std::vector &allProxyValues, std::vector &activeProxyValues); + void removeEmptyFittingParameters(std::vector > &fittingParameters); + void detrending(std::vector &myPoints, Crit3DProxyCombination myCombination, Crit3DInterpolationSettings *mySettings, Crit3DClimateParameters *myClimate, meteoVariable myVar, Crit3DTime myTime); @@ -73,7 +75,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector > parameters, std::vector &myPoints, Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr); - bool multipleDetrendingElevation(Crit3DProxyCombination myCombination, std::vector > parameters, std::vector &myPoints, + bool multipleDetrendingElevation(Crit3DProxyCombination myCombination, std::vector elevationParameters, std::vector &myPoints, Crit3DInterpolationSettings* mySettings, meteoVariable myVar, std::string &errorStr); bool getUseDetrendingVar(meteoVariable myVar); @@ -101,6 +103,9 @@ bool proxyValidity(std::vector &myPoints, int proxyPos, float stdDevThreshold, double &avg, double &stdDev); + bool proxyValidityWeighted(std::vector &myPoints, int proxyPos, + float stdDevThreshold, double &avg, double &stdDev); + bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings); bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings, diff --git a/interpolation/interpolationConstants.h b/interpolation/interpolationConstants.h index 4e368821..5cb13de0 100644 --- a/interpolation/interpolationConstants.h +++ b/interpolation/interpolationConstants.h @@ -31,6 +31,7 @@ { "orography", proxyHeight }, { "orogIndex", proxyOrogIndex }, { "urbanFraction", proxyUrbanFraction }, + { "urban", proxyUrbanFraction}, { "seaDistance", proxySeaDistance }, { "aspect", proxyAspect }, { "slope", proxySlope }, diff --git a/interpolation/interpolationSettings.cpp b/interpolation/interpolationSettings.cpp index 2cc0a65b..371ff4da 100644 --- a/interpolation/interpolationSettings.cpp +++ b/interpolation/interpolationSettings.cpp @@ -283,18 +283,26 @@ std::vector > Crit3DInterpolationSettings::getFittingParamet return fittingParameters; } +std::vector Crit3DInterpolationSettings::getProxyFittingParameters(int tempIndex) +{ + if (tempIndex < fittingParameters.size()) + return fittingParameters[tempIndex]; + else { + fittingParameters.resize(tempIndex + 1); + return fittingParameters[tempIndex]; + } +} + void Crit3DInterpolationSettings::setFittingParameters(const std::vector > &newFittingParameters) { fittingParameters = newFittingParameters; } -void Crit3DInterpolationSettings::setFittingParametersElevation(const std::vector &newFittingParameters) +void Crit3DInterpolationSettings::setSingleFittingParameters(std::vector &newFittingParameters, int paramIndex) { - if (fittingParameters.empty()) { - fittingParameters.push_back(newFittingParameters); - } else { - fittingParameters[0] = newFittingParameters; - } + if (fittingParameters.size() <= paramIndex) + fittingParameters.resize(paramIndex+1); + fittingParameters[paramIndex] = newFittingParameters; } void Crit3DInterpolationSettings::addFittingParameters(const std::vector > &newFittingParameters) @@ -314,20 +322,57 @@ void Crit3DInterpolationSettings::setFittingFunction(const std::vector &)> > &newFittingFunction) +void Crit3DInterpolationSettings::setSingleFittingFunction(const std::function &)> &newFittingFunction, unsigned int index) { - for (int i = 0; i < newFittingFunction.size(); i ++) - fittingFunction.push_back(newFittingFunction[i]); + if (fittingFunction.size() <= index) + fittingFunction.resize(index + 1); + fittingFunction[index] = newFittingFunction; + } TFittingFunction Crit3DInterpolationSettings::getChosenElevationFunction() { - return chosenElevationFunction; + int elPos = NODATA; + for (int i = 0; i < getProxyNr(); i++) + if (getProxyPragaName(getProxy(i)->getName()) == proxyHeight) + elPos = i; + + if (elPos != NODATA) + return getProxy(elPos)->getFittingFunctionName(); + else + return noFunction; } void Crit3DInterpolationSettings::setChosenElevationFunction(TFittingFunction chosenFunction) { - chosenElevationFunction = chosenFunction; + int elPos = NODATA; + for (int i = 0; i < getProxyNr(); i++) + if (getProxyPragaName(getProxy(i)->getName()) == proxyHeight) + elPos = i; + + double min = -20; + double max = 40; + + if (!getMinMaxTemperature().empty()) + { + min = getMinMaxTemperature()[0]; + max = getMinMaxTemperature()[1]; + } + + if (elPos != NODATA) + { + if (chosenFunction == piecewiseTwo) + getProxy(elPos)->setFittingParametersRange({-200, min-4, 0.002, -0.01, 5000, max+4, 0.01, 0.0015}); + else if (chosenFunction == piecewiseThree) + getProxy(elPos)->setFittingParametersRange({-200, min-4, 300, 0.002, -0.01, 5000, max+4, 1000, 0.007, 0.0015}); + else if (chosenFunction == piecewiseThreeFree) + getProxy(elPos)->setFittingParametersRange({-200, min-4, 300, 0.002, -0.01, -0.01, 5000, max+4, 1000, 0.007, 0.0015, 0.0015}); + else return; + + getProxy(elPos)->setFittingFunctionName(chosenFunction); + } + else + return; } void Crit3DInterpolationSettings::setMinMaxTemperature(double min, double max) @@ -391,7 +436,9 @@ void Crit3DInterpolationSettings::initialize() meteoGridAggrMethod = aggrAverage; meteoGridUpscaleFromDem = true; indexHeight = unsigned(NODATA); - chosenElevationFunction = piecewiseThreeFree; + + fittingFunction.clear(); + fittingParameters.clear(); isKrigingReady = false; precipitationAllZero = false; diff --git a/interpolation/interpolationSettings.h b/interpolation/interpolationSettings.h index cce7c344..87744cdb 100644 --- a/interpolation/interpolationSettings.h +++ b/interpolation/interpolationSettings.h @@ -117,6 +117,7 @@ void addProxyActive(bool value) { _isActiveList.push_back(value); } void setProxyActive(unsigned index, bool value) { _isActiveList[index] = value; } bool isProxyActive(unsigned index) { return _isActiveList[index]; } + std::vector getActiveList() { return _isActiveList; } void addProxySignificant(bool value) { _isSignificantList.push_back(value); } void setProxySignificant(unsigned index, bool value) { _isSignificantList[index] = value; } @@ -140,7 +141,6 @@ gis::Crit3DRasterGrid* currentDEM; //for TD TInterpolationMethod interpolationMethod; - TFittingFunction chosenElevationFunction; float minRegressionR2; bool useThermalInversion; @@ -263,12 +263,13 @@ void setMinPointsLocalDetrending(int newMinPointsLocalDetrending); std::vector> getFittingParameters() const; + std::vector getProxyFittingParameters(int tempIndex); void setFittingParameters(const std::vector> &newFittingParameters); - void setFittingParametersElevation(const std::vector &newFittingParameters); + void setSingleFittingParameters(std::vector &newFittingParameters, int paramIndex); void addFittingParameters(const std::vector > &newFittingParameters); std::vector &)> > getFittingFunction() const; void setFittingFunction(const std::vector &)> > &newFittingFunction); - void addFittingFunction(const std::vector &)> > &newFittingFunction); + void setSingleFittingFunction(const std::function &)> &newFittingFunction, unsigned int index); bool getProxiesComplete() const; void setProxiesComplete(bool newProxiesComplete); void clearFitting(); diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index 9b818576..f01e1ca9 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -139,6 +139,21 @@ double lapseRatePiecewiseThree_withSlope(double x, std::vector & par) return par[3]*x - par[3]*par[0]+par[1]; } +double detrendingLapseRatePiecewiseThree_withSlope(double x, std::vector & par) +{ + //xa (par[0],par[1]), xb-xa = par[2], par[3] is the slope of the middle piece, + //par[4] the slope of the first and last piece + par[2] = MAXVALUE(10, par[2]); + double xb = par[2]+par[0]; + + if (x < par[0]) + return par[4]*x; + else if (x > xb) + return par[4]*x; + else + return par[3]*x; +} + double lapseRatePiecewiseFree(double x, std::vector & par) { // the piecewise line is parameterized as follows @@ -171,6 +186,38 @@ double lapseRatePiecewiseFree(double x, std::vector & par) } } +double detrendingLapseRatePiecewiseFree(double x, std::vector & par) +{ + // the piecewise line is parameterized as follows + // the line passes through A(par[0];par[1])and B(par[0]+par[2];...) + //par [3] is the slope of the middle piece + //par[4] is the first slope. par[5] is the third slope + + // "y = mx + q" piecewise function; + double xb; + par[2] = MAXVALUE(10, par[2]); + // par[2] means the delta between the two quotes. It must be positive. + xb = par[0]+par[2]; + if (x < par[0]) + { + //m = par[4];; + //q = par[1]-m*par[0]; + return par[4]*x; + } + else if (x>xb) + { + //m = par[5]; + //q = m(-par[0]-par[2])+par[3]*par[2]+par[1]; + return (par[4]*par[0]) + (par[3]*par[2]) + par[5]*(x-xb); + } + else + { + //m = par[3]; + //q = m*(-par[0]) + par[1]; + return (par[4]*par[0]) + par[3]*(x-par[0]); + } +} + double lapseRatePiecewise_two(double x, std::vector & par) { // the piecewise line is parameterized as follows @@ -190,6 +237,25 @@ double lapseRatePiecewise_two(double x, std::vector & par) } } +double detrendingLapseRatePiecewise_two(double x, std::vector & par) +{ + // the piecewise line is parameterized as follows + // the line passes through A(par[0];par[1]). par[2] is the slope of the first line, par[3] the slope of the second + // "y = mx + q" piecewise function; + if (x < par[0]) + { + //m = par[2]; + //q = -par[2]*par[0]+par[1]; + return par[2]*x; + } + else + { + //m = par[3]: + //q = -par[3]*par[0]+par[1]; + return (par[2]*par[0]) + par[3]*(x-par[0]); + } +} + double functionSum(std::vector&)>>& functions, std::vector& x, std::vector >& par) { double result = 0.0; @@ -1241,22 +1307,25 @@ namespace interpolation std::vector >& parameters, std::vector >& parametersDelta, int maxIterationsNr, double myEpsilon, double deltaR2, std::vector >& x ,std::vector& y, - std::vector& weights) + std::vector& weights, unsigned int elevationPos) { int i,j; - int nrPredictors = int(parameters.size()); + int nrPredictors = 0; + for (int k = 0; k < parameters.size(); k++) + if (parameters[k].size() == 2) nrPredictors++; + if (elevationPos != NODATA) nrPredictors++; int nrData = int(y.size()); - std::vector nrParameters(nrPredictors); + std::vector nrParameters(parameters.size()); int nrParametersTotal = 0; - for (i=0; i> bestParameters(nrPredictors); + std::vector > bestParameters(parameters.size()); std::vector > correspondenceTag(2,std::vector(nrParametersTotal)); int counterTag = 0; - for (i=0; i ySim(nrData); int counter = 0; - //srand (unsigned(time(nullptr))); - std::random_device rd; - std::mt19937 gen(rd()); - std::normal_distribution normal_dis(0.5, 0.5); - double truncNormal; + //grigliato - do - { - fittingMarquardt_nDimension_noSquares(func,myFunc,parametersMin, parametersMax, - parameters, parametersDelta,correspondenceTag, maxIterationsNr, - myEpsilon, x, y, weights); + const int numSteps = 20; + std::vector steps = {2*(parametersMax[0][0]-parametersMin[0][0])/numSteps, 2*(parametersMax[0][1]-parametersMin[0][1])/numSteps}; - for (i=0;i> firstGuessParam = parameters; + bool exitFlag = 0; - if (R2 > (bestR2-deltaR2)) + for (int step = 1; step <= numSteps; ++step) + { + for (int dir = 0; dir < 2; ++dir) { - for (j=0;j (bestR2)) + for (int proxyIndex = 0; proxyIndex < nrPredictors; ++proxyIndex) { - for (i=0;i (bestR2-deltaR2)) + { + for (j=0;j (bestR2)) + { + for (i=0;i proxyIndex && !parameters[proxyIndex].empty()) + { + if (dir == 0) + parameters[proxyIndex][paramIndex] = MINVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * steps[paramIndex], parametersMax[proxyIndex][paramIndex]); + else + parameters[proxyIndex][paramIndex] = MAXVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * steps[paramIndex], parametersMin[proxyIndex][paramIndex]); + } + + /*for (i=0; i= 1.0); + parameters[i][j] = parametersMin[i][j] + (truncNormal)*(parametersMax[i][j]-parametersMin[i][j]); } } - bestR2 = R2; - } - R2Previous[nrMinima-1] = R2; +*/ - for (i=0;i= 1.0); - parameters[i][j] = parametersMin[i][j] + (truncNormal)*(parametersMax[i][j]-parametersMin[i][j]); + if ((counter > nrTrials) || ((R2Previous[0] != NODATA) && fabs(R2Previous[0]-R2Previous[nrMinima-1]) < deltaR2 )) + { + for (i=0;i 0.8 && R2Previous[nrMinima-1] > 0.8) && (fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2) ); - - for (i=0;i& weights) { int i; - int nrPredictors = int(parameters.size()); + int nrPredictors = 0; + for (int k = 0; k < parameters.size(); k++) + if (parameters[k].size() == 2) nrPredictors++; int nrData = int(y.size()); double mySSE, diffSSE, newSSE; static double VFACTOR = 10; @@ -1969,37 +2078,15 @@ namespace interpolation double R2; std::vector R2Previous(nrMinima,NODATA); std::vector ySim(nrData); - int counter = 0; - /*srand (unsigned(time(nullptr))); - std::random_device rd; - std::mt19937 gen(rd()); - std::normal_distribution normal_dis(0.5, 0.5); - //std::normal_distribution normal_dis(25, 20); - double truncNormal; - - std::vector > discreteParameters; - int nrDiscrete = 50; - std::uniform_int_distribution<> distribuzione(0, 49); - std::vector tempDiscrete; - for (int j = 0; j < parameters.size()-2; j++) - { - for (int i = 0; i < nrDiscrete; i++) - tempDiscrete.push_back(parametersMin[j]+i*((parametersMax[j]-parametersMin[j])/nrDiscrete)); - - discreteParameters.push_back(tempDiscrete); - tempDiscrete.clear(); - }*/ //grigliato - std::vector steps; - const int numSteps = 100; + const int numSteps = 50; if (parameters.size() == 4) - //steps = {50.0, 0.5, 0.00075, 0.00075}; steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 2*(parametersMax[2]-parametersMin[2])/numSteps, 2*(parametersMax[3]-parametersMin[3])/numSteps}; else if (parameters.size() == 6) - steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 2*(parametersMax[2]-parametersMin[2])/numSteps, 2*(parametersMax[3]-parametersMin[3])/numSteps,2*(parametersMax[4]-parametersMin[4])/numSteps,2*(parametersMax[5]-parametersMin[5])/numSteps }; + steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 4*(parametersMax[2]-parametersMin[2])/numSteps, 20*(parametersMax[3]-parametersMin[3])/numSteps,20*(parametersMax[3]-parametersMin[3])/numSteps,20*(parametersMax[3]-parametersMin[3])/numSteps }; else return false; int directions[] = {1, -1}; @@ -2057,70 +2144,8 @@ namespace interpolation if ((counter > nrTrials) || ((R2Previous[0] != NODATA) && fabs(R2Previous[0]-R2Previous[nrMinima-1]) < deltaR2 )) break; - - } - //end grigliato - - //random - /*do - { - fittingMarquardt_nDimension_noSquares_singleFunction(func,parametersMin, - parametersMax,parameters, - parametersDelta,maxIterationsNr, - myEpsilon,x,y,weights); - - for (i=0;i (bestR2-deltaR2)) - { - for (j=0;j (bestR2)) - { - for (j=0; j= 1.0); - parameters[j] = parametersMin[j] + (truncNormal)*(parametersMax[j]-parametersMin[j]); - } - - int indice = 0; - for (j=0; j= discreteParameters[j].size()); - parameters[j] = discreteParameters[j][indice]; - } - - } while( (counter < nrTrials) && !(R2Previous[0] > 0.797 && R2Previous[nrMinima-1] > 0.8) && ((R2Previous[0] == NODATA) || fabs(R2Previous[0]-R2Previous[nrMinima-1]) > deltaR2 )); -*/ for (j=0; j& par); double lapseRatePiecewiseForInterpolation(double x, std::vector & par); double lapseRatePiecewiseFree(double x, std::vector & par); + double detrendingLapseRatePiecewiseFree(double x, std::vector & par); double lapseRatePiecewiseThree_withSlope(double x, std::vector & par); + double detrendingLapseRatePiecewiseThree_withSlope(double x, std::vector & par); double lapseRatePiecewise_two(double x, std::vector & par); + double detrendingLapseRatePiecewise_two(double x, std::vector & par); double lapseRateFrei(double x, std::vector & par); double lapseRateFreiFree(double x, std::vector & par); double lapseRateRotatedSigmoid(double x, std::vector par); @@ -110,7 +113,7 @@ enum estimatedFunction {FUNCTION_CODE_SPHERICAL, FUNCTION_CODE_LINEAR, FUNCTION_ std::vector > ¶metersMin, std::vector > ¶metersMax, std::vector > ¶meters, std::vector > ¶metersDelta, int maxIterationsNr, double myEpsilon, double deltaR2, - std::vector >& x , std::vector& y, std::vector& weights); + std::vector >& x , std::vector& y, std::vector& weights, unsigned int elevationPos); bool fittingMarquardt_nDimension(double (*func)(std::vector &)> > &, std::vector &, std::vector >&), std::vector &)> > &myFunc, diff --git a/project/dialogInterpolation.cpp b/project/dialogInterpolation.cpp index 90f82f70..11ae05a7 100644 --- a/project/dialogInterpolation.cpp +++ b/project/dialogInterpolation.cpp @@ -146,6 +146,7 @@ DialogInterpolation::DialogInterpolation(Project *myProject) continue; elevationFunctionEdit.addItem(QString::fromStdString(itElFunc->first), QString::fromStdString(itElFunc->first)); } + QString elevationFunctionString = QString::fromStdString(getKeyStringElevationFunction(_interpolationSettings->getChosenElevationFunction())); int indexElFunction = elevationFunctionEdit.findData(elevationFunctionString); if (indexElFunction != -1) diff --git a/project/interpolationCmd.cpp b/project/interpolationCmd.cpp index 5058e788..d7adce14 100644 --- a/project/interpolationCmd.cpp +++ b/project/interpolationCmd.cpp @@ -277,7 +277,7 @@ bool interpolationRaster(std::vector &myPoints, C gis::getUtmXYFromRowColSinglePrecision(*outputGrid, myRow, myCol, &myX, &myY); float myZ = raster.value[myRow][myCol]; if (mySettings->getUseLocalDetrending()) - mySettings->setFittingParameters(raster.prepareParameters(myRow, myCol, mySettings->getSelectedCombination().getActiveProxySize())); + mySettings->setFittingParameters(raster.prepareParameters(myRow, myCol, mySettings->getSelectedCombination().getActiveList())); if (! isEqual(myZ, outputGrid->header->flag)) { if (getUseDetrendingVar(myVar)) diff --git a/project/project.cpp b/project/project.cpp index c425d196..15f17228 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -714,21 +714,21 @@ bool Project::loadParameters(QString parametersFileName) std::string elevationFuction = parameters->value("fitting_function").toString().toStdString(); if (fittingFunctionNames.find(elevationFuction) == fittingFunctionNames.end()) { - errorString = "Unknown function for elevation. Choose between: piecewise_two, triple_piecewise, free_triple_piecewise."; + errorString = "Unknown function for elevation. Remove the field from the .ini file or choose between: piecewise_two, triple_piecewise, free_triple_piecewise."; return false; } else - interpolationSettings.setChosenElevationFunction(fittingFunctionNames.at(elevationFuction)); + myProxy->setFittingFunctionName(fittingFunctionNames.at(elevationFuction)); if (parameters->contains("fitting_parameters")) { unsigned int nrParameters; - if (interpolationSettings.getChosenElevationFunction()== piecewiseTwo) + if (myProxy->getFittingFunctionName() == piecewiseTwo) nrParameters = 4; - else if (interpolationSettings.getChosenElevationFunction()== piecewiseThree) + else if (myProxy->getFittingFunctionName() == piecewiseThree) nrParameters = 5; - else if (interpolationSettings.getChosenElevationFunction()== piecewiseThreeFree) + else if (myProxy->getFittingFunctionName()== piecewiseThreeFree) nrParameters = 6; myList = parameters->value("fitting_parameters").toStringList(); @@ -743,11 +743,28 @@ bool Project::loadParameters(QString parametersFileName) } else { - interpolationSettings.setChosenElevationFunction(piecewiseTwo); + if (parameters->contains("fitting_parameters")) + { + myList = parameters->value("fitting_parameters").toStringList(); + + if (myList.size() == 8) + myProxy->setFittingFunctionName(piecewiseTwo); + else if (myList.size() == 10) + myProxy->setFittingFunctionName(piecewiseThree); + else if (myList.size() == 12) + myProxy->setFittingFunctionName(piecewiseThreeFree); + else + { + errorString = "Wrong number of fitting parameters for proxy: " + name_; + return false; + } + myProxy->setFittingParametersRange(StringListToDouble(myList)); + } } } else { + myProxy->setFittingFunctionName(linear); if(parameters->contains("fitting_parameters")) { unsigned int nrParameters = 2; @@ -2431,8 +2448,8 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT std::vector subsetInterpolationPoints; localSelection(interpolationPoints, subsetInterpolationPoints, x, y, z, interpolationSettings); - if (interpolationSettings.getUseLocalDetrending()) - interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col, myCombination.getActiveProxySize())); + if (interpolationSettings.getUseLocalDetrending()) + interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col, myCombination.getActiveList())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, meteoPoints, nrMeteoPoints, myVar, myTime, errorStdStr)) { @@ -2443,6 +2460,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT myRaster->value[row][col] = interpolate(subsetInterpolationPoints, &interpolationSettings, meteoSettings, myVar, x, y, z, proxyValues, true); myRaster->setParametersForRowCol(row, col, interpolationSettings.getFittingParameters()); + interpolationSettings.clearFitting(); interpolationSettings.setCurrentCombination(interpolationSettings.getSelectedCombination()); } } @@ -2733,7 +2751,7 @@ bool Project::interpolationGrid(meteoVariable myVar, const Crit3DTime& myTime) { std::vector subsetInterpolationPoints; localSelection(interpolationPoints, subsetInterpolationPoints, myX, myY, myZ, interpolationSettings); - interpolationSettings.setFittingParameters(meteoGridDbHandler->meteoGrid()->dataMeteoGrid.prepareParameters(row, col, myCombination.getActiveProxySize())); + interpolationSettings.setFittingParameters(meteoGridDbHandler->meteoGrid()->dataMeteoGrid.prepareParameters(row, col, myCombination.getActiveList())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, meteoPoints, nrMeteoPoints, myVar, myTime, errorStdStr)) { @@ -3058,6 +3076,7 @@ void Project::saveProxies() if (myProxy->getGridName() != "") parameters->setValue("raster", getRelativePath(QString::fromStdString(myProxy->getGridName()))); if (myProxy->getStdDevThreshold() != NODATA) parameters->setValue("stddev_threshold", QString::number(myProxy->getStdDevThreshold())); if (myProxy->getFittingParametersRange().size() > 0) parameters->setValue("fitting_parameters", DoubleVectorToStringList(myProxy->getFittingParametersRange())); + if (getProxyPragaName(myProxy->getName()) == proxyHeight && myProxy->getFittingFunctionName() != noFunction) parameters->setValue("fitting_function", QString::fromStdString(getKeyStringElevationFunction(myProxy->getFittingFunctionName()))); parameters->endGroup(); } } diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 50a67dd4..4414257e 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -406,7 +406,8 @@ void Crit3DLocalProxyWidget::plot() point.setX(proxyVal); point.setY(varValue); QString text = "id: " + QString::fromStdString(meteoPoints[subsetInterpolationPoints[i].index].id) + "\n" - + "name: " + QString::fromStdString(meteoPoints[subsetInterpolationPoints[i].index].name); + + "name: " + QString::fromStdString(meteoPoints[subsetInterpolationPoints[i].index].name) + "\n" + + "weight: " + QString::number(subsetInterpolationPoints[i].regressionWeight); if (subsetInterpolationPoints[i].isMarked) { pointListMarked.append(point); @@ -521,118 +522,93 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) if (toggled && subsetInterpolationPoints.size() != 0 && currentVariable == myVar) { - if (comboAxisX.currentText() == "elevation") + if (parameters.size() > proxyPos) { - xMin = getZmin(subsetInterpolationPoints); - xMax = getZmax(subsetInterpolationPoints); - float myY; - - if (interpolationSettings->getUseMultipleDetrending()) + if (parameters[proxyPos].size() > 2) { - if (parameters.empty() || (parameters[proxyPos].size() != 5 && parameters[proxyPos].size() != 6 && parameters[proxyPos].size() != 4)) - return; + xMin = getZmin(subsetInterpolationPoints); + xMax = getZmax(subsetInterpolationPoints); + float myY; - if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree) + if (interpolationSettings->getUseMultipleDetrending()) { - std::vector xVector; - for (int m = xMin; m < xMax; m += 5) - xVector.push_back(m); + if ((parameters[proxyPos].size() != 5 && parameters[proxyPos].size() != 6 && parameters[proxyPos].size() != 4)) + return; - for (int p = 0; p < xVector.size(); p++) + if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree) { - point.setX(xVector[p]); - point.setY(lapseRatePiecewiseThree_withSlope(xVector[p], parameters[proxyPos])); - point_vector.append(point); + std::vector xVector; + for (int m = xMin; m < xMax; m += 5) + xVector.push_back(m); + + for (int p = 0; p < xVector.size(); p++) + { + point.setX(xVector[p]); + point.setY(lapseRatePiecewiseThree_withSlope(xVector[p], parameters[proxyPos])); + point_vector.append(point); + } } - } - else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseTwo) - { - float lapseRateH0 = parameters[proxyPos][0]; - float lapseRateT0 = parameters[proxyPos][1]; - float slope1 = parameters[proxyPos][2]; - float slope2 = parameters[proxyPos][3]; - - if (xMin < lapseRateH0) + else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseTwo) { - myY = lapseRateT0 + slope1 * (xMin - lapseRateH0); - point.setX(xMin); + float lapseRateH0 = parameters[proxyPos][0]; + float lapseRateT0 = parameters[proxyPos][1]; + float slope1 = parameters[proxyPos][2]; + float slope2 = parameters[proxyPos][3]; + + if (xMin < lapseRateH0) + { + myY = lapseRateT0 + slope1 * (xMin - lapseRateH0); + point.setX(xMin); + point.setY(myY); + point_vector.append(point); + } + + point.setX(lapseRateH0); + point.setY(lapseRateT0); + point_vector.append(point); + + myY = lapseRateT0 + slope2 * (xMax - lapseRateH0); + point.setX(xMax); point.setY(myY); point_vector.append(point); } + else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeFree) + { + std::vector xVector; + for (int m = xMin; m < xMax; m += 5) + xVector.push_back(m); - point.setX(lapseRateH0); - point.setY(lapseRateT0); - point_vector.append(point); + for (int p = 0; p < xVector.size(); p++) + { + point.setX(xVector[p]); + point.setY(lapseRatePiecewiseFree(xVector[p], parameters[proxyPos])); + point_vector.append(point); + } - myY = lapseRateT0 + slope2 * (xMax - lapseRateH0); - point.setX(xMax); - point.setY(myY); - point_vector.append(point); - } - else if (interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThreeFree) - { - std::vector xVector; - for (int m = xMin; m < xMax; m += 5) - xVector.push_back(m); - - for (int p = 0; p < xVector.size(); p++) - { - point.setX(xVector[p]); - point.setY(lapseRatePiecewiseFree(xVector[p], parameters[proxyPos])); - point_vector.append(point); } - } - /*if (interpolationSettings->getProxy(proxyPos)->getInversionIsSignificative()) - { - if (xMin < interpolationSettings->getProxy(proxyPos)->getLapseRateH0()) - { - point.setX(xMin); - point.setY(lapseRateT0); - point_vector.append(point); - }*/ - + } + else + { + xMin = getProxyMinValue(subsetInterpolationPoints, proxyPos); + xMax = getProxyMaxValue(subsetInterpolationPoints, proxyPos); - /*} - else - { - float myY = lapseRateT0 + regressionSlope * xMin; - point.setX(xMin); - point.setY(myY); - point_vector.append(point); + if (parameters[proxyPos].empty()) + return; - myY = lapseRateT0 + regressionSlope * xMax; - point.setX(xMax); - point.setY(myY); - point_vector.append(point); - }*/ + float slope = parameters[proxyPos][0]; + float intercept = parameters[proxyPos][1]; - } + float myY = intercept + slope * xMin; + point.setX(xMin); + point.setY(myY); + point_vector.append(point); - /*if (interpolationSettings->getProxy(proxyPos)->getRegressionR2() != NODATA) - { - r2.setText(QString("%1").arg(interpolationSettings->getProxy(proxyPos)->getRegressionR2(), 0, 'f', 2)); + myY = intercept + slope * xMax; + point.setX(xMax); + point.setY(myY); + point_vector.append(point); } - lapseRate.setText(QString("%1").arg(regressionSlope*1000, 0, 'f', 2));*/ - } - else - { - //TODO lineari - /*xMin = getProxyMinValue(subsetInterpolationPoints, proxyPos); - xMax = getProxyMaxValue(subsetInterpolationPoints, proxyPos); - - float slope = parameters[proxyPos][0]; - float intercept = parameters[proxyPos][1]; - - float myY = intercept + slope * xMin; - point.setX(xMin); - point.setY(myY); - point_vector.append(point); - - myY = intercept + slope * xMax; - point.setX(xMax); - point.setY(myY); - point_vector.append(point);*/ } chartView->drawModelLapseRate(point_vector); } From 4ec284f8044c9cd57f5ab2639fc6a4cb2ccdc191 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 12 Jul 2024 17:13:23 +0200 Subject: [PATCH 133/179] update interface --- criteria1DWidget/criteria1DWidget.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/criteria1DWidget/criteria1DWidget.cpp b/criteria1DWidget/criteria1DWidget.cpp index c6eadb70..ce837a15 100644 --- a/criteria1DWidget/criteria1DWidget.cpp +++ b/criteria1DWidget/criteria1DWidget.cpp @@ -171,10 +171,15 @@ Criteria1DWidget::Criteria1DWidget() waterContentGroup->setFixedWidth(this->width() * widthRatio); carbonNitrogenGroup->setFixedWidth(this->width() * widthRatio); - infoCaseGroup->setTitle("Case"); - infoCropGroup->setTitle("Crop"); + QFont normalFont, boldFont; + boldFont.setBold(true); + normalFont.setBold(false); + + infoCaseGroup->setFont(boldFont); + infoCaseGroup->setTitle("Case study"); infoMeteoGroup->setTitle("Meteo"); infoSoilGroup->setTitle("Soil"); + infoCropGroup->setTitle("Crop"); laiParametersGroup->setTitle("Crop parameters"); rootParametersGroup->setTitle("Root parameters"); irrigationParametersGroup->setTitle("Irrigation parameters"); @@ -182,6 +187,7 @@ Criteria1DWidget::Criteria1DWidget() waterContentGroup->setTitle("Water Content variable"); carbonNitrogenGroup->setTitle("Carbon Nitrogen variable"); + caseListComboBox.setFont(normalFont); caseInfoLayout->addWidget(&caseListComboBox); cropInfoLayout->addWidget(cropId, 0, 0); @@ -435,9 +441,9 @@ Criteria1DWidget::Criteria1DWidget() carbonNitrogenGroup->setLayout(carbonNitrogenLayout); infoLayout->addWidget(infoCaseGroup); - infoLayout->addWidget(infoCropGroup); infoLayout->addWidget(infoMeteoGroup); infoLayout->addWidget(infoSoilGroup); + infoLayout->addWidget(infoCropGroup); infoLayout->addWidget(laiParametersGroup); infoLayout->addWidget(rootParametersGroup); infoLayout->addWidget(irrigationParametersGroup); From 4286c084f7cf59bdbda5aca4682dd4210f51830a Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Mon, 15 Jul 2024 12:22:44 +0200 Subject: [PATCH 134/179] fix multiple detrending --- interpolation/interpolation.cpp | 20 ++++++++++---------- interpolation/interpolationSettings.cpp | 2 +- mathFunctions/furtherMathFunctions.cpp | 17 ++--------------- project/project.cpp | 4 ++++ 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 99a34930..0b91d694 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1068,10 +1068,11 @@ void localSelection(vector &inputPoints, vector < for (i=0; i< selectedPoints.size(); i++) { //selectedPoints[i].regressionWeight = MAXVALUE(1 - selectedPoints[i].distance / (std::pow(maxDistance, 16.0/15.0)), EPSILON); - selectedPoints[i].regressionWeight = MAXVALUE(std::exp(-std::pow(selectedPoints[i].distance/(0.8*maxDistance),3.0)),EPSILON); + //selectedPoints[i].regressionWeight = MAXVALUE(std::exp(-std::pow(selectedPoints[i].distance/((4/5*maxDistance)),7.0)),EPSILON); + selectedPoints[i].regressionWeight = MAXVALUE((-(1/std::pow(maxDistance,4)*(std::pow(selectedPoints[i].distance,4)))+1),EPSILON); //selectedPoints[i].regressionWeight = 1; - selectedPoints[i].heightWeight = 1./((2./maxHeightDelta)*selectedPoints[i].point->z+1); - //selectedPoints[i].heightWeight = 1; + //selectedPoints[i].heightWeight = 1./((2./maxHeightDelta)*selectedPoints[i].point->z+1); + selectedPoints[i].heightWeight = 1; } mySettings.setLocalRadius(float(maxDistance)); } @@ -1689,9 +1690,9 @@ bool multipleDetrendingMain(std::vector &myPoints elevationCombination.resetCombination(mySettings->getSelectedCombination().getProxySize()); elevationCombination.setProxyActive(elevationPos, true); - if (parameters.empty()) { + if (parameters.empty()) parameters.resize(elevationPos + 1); - } + if (!multipleDetrendingElevation(elevationCombination, parameters[elevationPos], myPoints, mySettings, myVar, errorStr)) return false; @@ -1871,7 +1872,7 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st interpolation::bestFittingMarquardt_nDimension_singleFunction(*func, nrMaxStep, 4, parametersMin[elevationPos], parametersMax[elevationPos], parameters[elevationPos], parametersDelta[elevationPos], 100, 0.005, 0.002, predictors, predictands, weights); - mySettings->setSingleFittingFunction(myFunc[elevationPos], elevationPos); + mySettings->setSingleFittingParameters(parameters[elevationPos], elevationPos); @@ -2104,7 +2105,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vector> parameters; std::vector&)>> myFunc(mySettings->getCurrentCombination().getProxySize(), nullptr); - unsigned int nrMaxStep = 100; + unsigned int nrMaxStep = 10; if (parameters.empty()) nrMaxStep *= 10; @@ -2130,7 +2131,7 @@ bool multipleDetrending(Crit3DProxyCombination othersCombination, std::vectorsetSingleFittingFunction(functionLinear, i); } k++; - myFunc[i] = functionLinear; + myFunc.push_back(functionLinear); } } - std::vector proxyValues; // detrending diff --git a/interpolation/interpolationSettings.cpp b/interpolation/interpolationSettings.cpp index 371ff4da..683472d1 100644 --- a/interpolation/interpolationSettings.cpp +++ b/interpolation/interpolationSettings.cpp @@ -301,7 +301,7 @@ void Crit3DInterpolationSettings::setFittingParameters(const std::vector &newFittingParameters, int paramIndex) { if (fittingParameters.size() <= paramIndex) - fittingParameters.resize(paramIndex+1); + fittingParameters.resize(paramIndex+1); fittingParameters[paramIndex] = newFittingParameters; } diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index f01e1ca9..d85a3e29 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -1402,7 +1402,7 @@ namespace interpolation } counter++; - if (!parameters.size() > proxyIndex && !parameters[proxyIndex].empty()) + if (parameters.size() > proxyIndex && !parameters[proxyIndex].empty()) { if (dir == 0) parameters[proxyIndex][paramIndex] = MINVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * steps[paramIndex], parametersMax[proxyIndex][paramIndex]); @@ -1410,19 +1410,6 @@ namespace interpolation parameters[proxyIndex][paramIndex] = MAXVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * steps[paramIndex], parametersMin[proxyIndex][paramIndex]); } - /*for (i=0; i= 1.0); - parameters[i][j] = parametersMin[i][j] + (truncNormal)*(parametersMax[i][j]-parametersMin[i][j]); - } - } -*/ - - if ((counter > nrTrials) || ((R2Previous[0] != NODATA) && fabs(R2Previous[0]-R2Previous[nrMinima-1]) < deltaR2 )) { for (i=0;i steps; - const int numSteps = 50; + const int numSteps = 30; if (parameters.size() == 4) steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 2*(parametersMax[2]-parametersMin[2])/numSteps, 2*(parametersMax[3]-parametersMin[3])/numSteps}; else if (parameters.size() == 6) diff --git a/project/project.cpp b/project/project.cpp index 15f17228..d7178f32 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2437,6 +2437,10 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT { for (long col = 0; col < myHeader.nrCols; col++) { + + if (row == 113 && col == 32) + int a = 0; + interpolationSettings.setProxiesComplete(true); float z = DEM.value[row][col]; From 128797aea5ee3fb3117d04e87bfe661754f92b2b Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Mon, 15 Jul 2024 12:35:43 +0200 Subject: [PATCH 135/179] remove debug lines --- project/project.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index d7178f32..15f17228 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2437,10 +2437,6 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT { for (long col = 0; col < myHeader.nrCols; col++) { - - if (row == 113 && col == 32) - int a = 0; - interpolationSettings.setProxiesComplete(true); float z = DEM.value[row][col]; From b7f58033bda61df91b1f1ec53029d11d84804c71 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 15 Jul 2024 14:47:48 +0200 Subject: [PATCH 136/179] clean VINE3D --- grapevine/grapevine.cpp | 15 ++------------- grapevine/grapevine.h | 6 +++--- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/grapevine/grapevine.cpp b/grapevine/grapevine.cpp index 3e112e07..22125020 100644 --- a/grapevine/grapevine.cpp +++ b/grapevine/grapevine.cpp @@ -113,11 +113,6 @@ void Vine3D_Grapevine::resetLayers() { for (int i=0 ; i < nrMaxLayers ; i++) { - //psiSoilProfile[i] = NODATA ; - //soilWaterContentProfile[i]= NODATA ; - //soilWaterContentProfileFC[i]= NODATA; - //soilWaterContentProfileWP[i]= NODATA; - //soilFieldCapacity[i] = NODATA; fractionTranspirableSoilWaterProfile[i]= NODATA; stressCoefficientProfile[i] = NODATA; transpirationInstantLayer[i] = NODATA; @@ -126,15 +121,10 @@ void Vine3D_Grapevine::resetLayers() } } -bool Vine3D_Grapevine::initializeLayers(int myMaxLayers) +void Vine3D_Grapevine::initializeLayers(int myMaxLayers) { nrMaxLayers = myMaxLayers; - //psiSoilProfile = (double *) calloc(nrLayers, sizeof(double)); - //soilWaterContentProfile = (double *) calloc(nrLayers, sizeof(double)); - //soilWaterContentProfileFC = (double *) calloc(nrLayers, sizeof(double)); - //soilWaterContentProfileWP = (double *) calloc(nrLayers, sizeof(double)); - //soilFieldCapacity = (double *) calloc (nrLayers, sizeof(double)); fractionTranspirableSoilWaterProfile = static_cast (calloc(size_t(nrMaxLayers), sizeof(double))); stressCoefficientProfile = static_cast (calloc(size_t(nrMaxLayers), sizeof(double))); transpirationInstantLayer = static_cast (calloc(size_t(nrMaxLayers), sizeof(double))); @@ -143,10 +133,9 @@ bool Vine3D_Grapevine::initializeLayers(int myMaxLayers) currentProfile = static_cast (calloc(size_t(nrMaxLayers), sizeof(double))); resetLayers(); - - return true; } + void Vine3D_Grapevine::setDate (Crit3DTime myTime) { myDoy = getDoyFromDate(myTime.date); diff --git a/grapevine/grapevine.h b/grapevine/grapevine.h index 12a4eb76..a0d18faa 100644 --- a/grapevine/grapevine.h +++ b/grapevine/grapevine.h @@ -192,13 +192,13 @@ struct Crit3DModelCase { int id; Crit3DLanduse landuse; - //int soilIndex; + int soilIndex; float shootsPerPlant; float plantDensity; float maxLAIGrass; int trainingSystem; - float maxIrrigationRate; //[mm/h] + float maxIrrigationRate; // [mm h-1] int soilLayersNr; double soilTotalDepth; @@ -393,7 +393,7 @@ Vine3D_Grapevine(); //void initializeGrapevineModel(TVineCultivar* cultivar, double secondsPerStep); - bool initializeLayers(int myMaxLayers); + void initializeLayers(int myMaxLayers); bool initializeStatePlant(int doy, Crit3DModelCase *vineField); void resetLayers(); From fb31d4c9e2e2eccdddf1b5f51ff2c6d3240f7fc5 Mon Sep 17 00:00:00 2001 From: Gabriele Antolini Date: Mon, 15 Jul 2024 16:39:34 +0200 Subject: [PATCH 137/179] fixed export meteo grid to csv --- dbMeteoGrid/dbMeteoGrid.cpp | 2 +- gis/gis.cpp | 2 +- gis/gis.h | 2 +- graphics/mapGraphicsRasterObject.cpp | 2 +- meteo/meteoGrid.cpp | 2 +- project/project.cpp | 11 ++++++++--- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/dbMeteoGrid/dbMeteoGrid.cpp b/dbMeteoGrid/dbMeteoGrid.cpp index 09f093b0..a39a9b2d 100644 --- a/dbMeteoGrid/dbMeteoGrid.cpp +++ b/dbMeteoGrid/dbMeteoGrid.cpp @@ -4126,7 +4126,7 @@ bool Crit3DMeteoGridDbHandler::MeteoGridToRasterFlt(double cellSize, const gis:: { myGrid.getXY(row, col, utmx, utmy); gis::getLatLonFromUtm(gisSettings, utmx, utmy, &lat, &lon); - gis::getGridRowColFromXY (latlonHeader, lon, lat, &dataGridRow, &dataGridCol); + gis::getGridRowColFromLonLat (latlonHeader, lon, lat, &dataGridRow, &dataGridCol); if (dataGridRow < 0 || dataGridRow >= latlonHeader.nrRows || dataGridCol < 0 || dataGridCol >= latlonHeader.nrCols) { myValue = NODATA; diff --git a/gis/gis.cpp b/gis/gis.cpp index 934b6b56..eb099139 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -791,7 +791,7 @@ namespace gis v->col = int(floor((p.x - myHeader.llCorner.x) / myHeader.cellSize)); } - void getGridRowColFromXY (const Crit3DLatLonHeader& myHeader, double myX, double myY, int *row, int *col) + void getGridRowColFromLonLat(const Crit3DLatLonHeader& myHeader, double myX, double myY, int *row, int *col) { *row = int(floor((myY - myHeader.llCorner.latitude) / myHeader.dy)); *col = int(floor((myX - myHeader.llCorner.longitude) / myHeader.dx)); diff --git a/gis/gis.h b/gis/gis.h index 547aac3d..9130802e 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -217,7 +217,7 @@ void getRowColFromXY(const Crit3DRasterHeader& myHeader, double myX, double myY, int *row, int *col); void getRowColFromXY(const Crit3DRasterHeader& myHeader, const Crit3DUtmPoint& p, int *row, int *col); void getRowColFromXY(const Crit3DRasterHeader& myHeader, const Crit3DUtmPoint& p, Crit3DRasterCell* v); - void getGridRowColFromXY(const Crit3DLatLonHeader& myHeader, double myX, double myY, int *row, int *col); + void getGridRowColFromLonLat(const Crit3DLatLonHeader& myHeader, double myX, double myY, int *row, int *col); void getRowColFromLatLon(const Crit3DLatLonHeader &latLonHeader, const Crit3DGeoPoint& p, int *myRow, int *myCol); bool isOutOfGridRowCol(int myRow, int myCol, const Crit3DRasterGrid &rasterGrid); diff --git a/graphics/mapGraphicsRasterObject.cpp b/graphics/mapGraphicsRasterObject.cpp index 24a42877..ebabc397 100644 --- a/graphics/mapGraphicsRasterObject.cpp +++ b/graphics/mapGraphicsRasterObject.cpp @@ -519,7 +519,7 @@ bool RasterObject::getRowCol(gis::Crit3DGeoPoint geoPoint, int* row, int* col) if (! this->isGrid) return false; - gis::getGridRowColFromXY(this->latLonHeader, geoPoint.longitude, geoPoint.latitude, row, col); + gis::getGridRowColFromLonLat(this->latLonHeader, geoPoint.longitude, geoPoint.latitude, row, col); // check out of grid if (gis::isOutOfGridRowCol(*row, *col, this->latLonHeader)) diff --git a/meteo/meteoGrid.cpp b/meteo/meteoGrid.cpp index 26af6a75..3e688159 100644 --- a/meteo/meteoGrid.cpp +++ b/meteo/meteoGrid.cpp @@ -988,7 +988,7 @@ void Crit3DMeteoGrid::saveRowColfromZone(gis::Crit3DRasterGrid* zoneGrid, std::v double utmX = x; double utmY = y; gis::getLatLonFromUtm(_gisSettings, utmX, utmY, &y, &x); - gis::getGridRowColFromXY(_gridStructure.header(), x, y, &myRow, &myCol); + gis::getGridRowColFromLonLat(_gridStructure.header(), x, y, &myRow, &myCol); } else { diff --git a/project/project.cpp b/project/project.cpp index 15f17228..860cc672 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -3709,7 +3709,7 @@ void Project::showLocalProxyGraph(gis::Crit3DGeoPoint myPoint, gis::Crit3DRaster } if (this->meteoGridLoaded && !this->meteoGridDbHandler->meteoGrid()->dataMeteoGrid.parametersCell.empty()) { - gis::getGridRowColFromXY(meteoGridDbHandler->meteoGrid()->gridStructure().header(), myPoint.longitude, myPoint.latitude, &row, &col); + gis::getGridRowColFromLonLat(meteoGridDbHandler->meteoGrid()->gridStructure().header(), myPoint.longitude, myPoint.latitude, &row, &col); parameters = meteoGridDbHandler->meteoGrid()->dataMeteoGrid.getParametersFromRowCol(row, col); } @@ -4200,11 +4200,16 @@ bool Project::exportMeteoGridToCsv(QString fileName) for (int col = 0; col < meteoGridDbHandler->meteoGrid()->dataMeteoGrid.header->nrCols; col++) { float value = meteoGridDbHandler->meteoGrid()->dataMeteoGrid.value[row][col]; - std::string id = meteoGridDbHandler->meteoGrid()->meteoPoints()[row][col]->id; - std::string name = meteoGridDbHandler->meteoGrid()->meteoPoints()[row][col]->name; if (value != NO_ACTIVE && value != NODATA) { + int newRow = row; + if (! meteoGridDbHandler->meteoGrid()->gridStructure().isUTM()) + newRow = meteoGridDbHandler->meteoGrid()->gridStructure().nrRow() - 1 - row; + + std::string id = meteoGridDbHandler->meteoGrid()->meteoPoints()[newRow][col]->id; + std::string name = meteoGridDbHandler->meteoGrid()->meteoPoints()[newRow][col]->name; + out << QString::fromStdString(id + ',' + name + ',') + QString::number(value) + "\n"; } } From e522c5e7db92d4566ebedfcd1e85e989ada69675 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 16 Jul 2024 16:19:06 +0200 Subject: [PATCH 138/179] update 3D --- soilFluxes3D/soilFluxes3D.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/soilFluxes3D/soilFluxes3D.cpp b/soilFluxes3D/soilFluxes3D.cpp index 536337c0..33d9fc19 100644 --- a/soilFluxes3D/soilFluxes3D.cpp +++ b/soilFluxes3D/soilFluxes3D.cpp @@ -658,7 +658,7 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief getTotalWaterContent - * \return total water content [m^3] + * \return total water content [m3] */ double DLL_EXPORT __STDCALL getTotalWaterContent() { @@ -823,10 +823,15 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, void DLL_EXPORT __STDCALL initializeBalance() { InitializeBalanceWater(); + if (myStructure.computeHeat) + { initializeBalanceHeat(); + } else + { balanceWholePeriod.heatMBR = 1.; + } } From 42997350b8ef3bd9e2eea14760d74263fcd7df38 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 16 Jul 2024 16:51:03 +0200 Subject: [PATCH 139/179] fix model pause --- gis/color.h | 2 +- soilFluxes3D/water.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gis/color.h b/gis/color.h index 526313e2..375c04a0 100644 --- a/gis/color.h +++ b/gis/color.h @@ -15,7 +15,7 @@ short blue; Crit3DColor(); - Crit3DColor(short,short,short); + Crit3DColor(short, short, short); }; class Crit3DColorScale { diff --git a/soilFluxes3D/water.cpp b/soilFluxes3D/water.cpp index f418f611..4d536f93 100644 --- a/soilFluxes3D/water.cpp +++ b/soilFluxes3D/water.cpp @@ -323,7 +323,7 @@ bool waterFlowComputation(double deltaT) isValidStep = waterBalance(deltaT, approximationNr); if (getForcedHalvedTime()) return (false); } - while ((!isValidStep) && (++approximationNr < myParameters.maxApproximationsNumber)); + while ((! isValidStep) && (++approximationNr < myParameters.maxApproximationsNumber)); return isValidStep; } @@ -368,7 +368,7 @@ bool computeWater(double maxTime, double *acceptedTime) isStepOK = waterFlowComputation(*acceptedTime); - if (!isStepOK) restoreWater(); + if (! isStepOK) restoreWater(); } return (isStepOK); } From b4a3d0c0c59d006dc68685cd83539a44576b9036 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 17 Jul 2024 15:16:42 +0200 Subject: [PATCH 140/179] update 3d colors --- gis/color.cpp | 17 +++++++++++++++++ gis/color.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/gis/color.cpp b/gis/color.cpp index bbcead0a..f48cbbfc 100644 --- a/gis/color.cpp +++ b/gis/color.cpp @@ -365,6 +365,23 @@ bool reverseColorScale(Crit3DColorScale* myScale) } +void mixColor(const Crit3DColor &backColor, const Crit3DColor &foreColor, Crit3DColor &colorOut, float alpha) +{ + if (alpha == 0) + { + colorOut.red = backColor.red; + colorOut.green = backColor.green; + colorOut.blue = backColor.blue; + } + else + { + colorOut.red = std::min(255, int(backColor.red * (1. - alpha)) + int(foreColor.red * alpha)); + colorOut.green = std::min(255, int(backColor.green * (1. - alpha)) + int(foreColor.green * alpha)); + colorOut.blue = std::min(255, int(backColor.blue * (1. - alpha)) +int( foreColor.blue * alpha)); + } +} + + /*! * \brief roundColorScale round colorScale values on the second (or third) digit of each range. * It requires that nrColors is a multiply of nrIntervals for a correct visualization in the colors legend. diff --git a/gis/color.h b/gis/color.h index 375c04a0..ae378f44 100644 --- a/gis/color.h +++ b/gis/color.h @@ -75,5 +75,7 @@ bool setSurfaceWaterScale(Crit3DColorScale* myScale); bool setLAIScale(Crit3DColorScale* myScale); + void mixColor(const Crit3DColor &backColor, const Crit3DColor &foreColor, Crit3DColor &colorOut, float alpha); + #endif // CRIT3DCOLOR_H From 631749fc0d93de60626c1ea67240068613cec866 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 17 Jul 2024 17:53:59 +0200 Subject: [PATCH 141/179] update 3D --- gis/color.cpp | 5 +++-- gis/color.h | 4 ++++ meteo/meteo.cpp | 1 + project/project.cpp | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gis/color.cpp b/gis/color.cpp index f48cbbfc..1ae2aad2 100644 --- a/gis/color.cpp +++ b/gis/color.cpp @@ -56,6 +56,7 @@ Crit3DColorScale::Crit3DColorScale() _maximum = NODATA; _isFixedRange = false; _isHideOutliers = false; + _isTransparent = false; _classification = classificationMethod::EqualInterval; } @@ -212,8 +213,8 @@ bool setSlopeStabilityScale(Crit3DColorScale* myScale) myScale->keyColor[0] = Crit3DColor(128, 0, 128); /*!< violet */ myScale->keyColor[1] = Crit3DColor(255, 0, 0); /*!< red */ myScale->keyColor[2] = Crit3DColor(255, 255, 0); /*!< yellow */ - myScale->keyColor[3] = Crit3DColor(196, 196, 32); /*!< yellow/green */ - myScale->keyColor[4] = Crit3DColor(64, 196, 64); /*!< green */ + myScale->keyColor[3] = Crit3DColor(64, 196, 64); /*!< green */ + myScale->keyColor[4] = Crit3DColor(128, 255, 128); /*!< light green */ return(myScale->classify()); } diff --git a/gis/color.h b/gis/color.h index ae378f44..64a1fe88 100644 --- a/gis/color.h +++ b/gis/color.h @@ -26,6 +26,7 @@ double _minimum, _maximum; bool _isFixedRange; bool _isHideOutliers; + bool _isTransparent; int _classification; public: @@ -55,6 +56,9 @@ void setHideOutliers(bool hideOutliers) { _isHideOutliers = hideOutliers; } bool isHideOutliers() { return _isHideOutliers; } + + void setTransparent(bool transparent) { _isTransparent = transparent; } + bool isTransparent() { return _isTransparent; } }; bool setDefaultScale(Crit3DColorScale* myScale); diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index d96851af..21709b86 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -790,6 +790,7 @@ bool setColorScale(meteoVariable variable, Crit3DColorScale *colorScale) || variable == snowLiquidWaterContent || variable == snowMelt) { colorScale->setHideOutliers(true); + colorScale->setTransparent(true); } break; case snowAge: diff --git a/project/project.cpp b/project/project.cpp index 860cc672..1f311929 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -3230,7 +3230,7 @@ bool Project::loadProject() if (dbPointsFileName != "") if (! loadMeteoPointsDB(dbPointsFileName)) { - errorString = "load Meteo Points DB failed"; + errorString = "load Meteo Points DB failed:\n" + dbPointsFileName; errorType = ERROR_DBPOINT; logError(); return false; From 75cb949c347c7ea5c8ca672f25e7a73f086b3923 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 17 Jul 2024 17:55:54 +0200 Subject: [PATCH 142/179] update comments --- soil/soil.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soil/soil.cpp b/soil/soil.cpp index 05ef7289..8806509e 100644 --- a/soil/soil.cpp +++ b/soil/soil.cpp @@ -763,8 +763,8 @@ namespace soil { double suctionStress = -waterPotential * getDegreeOfSaturation(); // [kPa] - double slopeAngle = std::max(asin(slope), EPSILON); - double frictionAngle = horizonPtr->frictionAngle * DEG_TO_RAD; + double slopeAngle = std::max(asin(slope), EPSILON); // [rad] + double frictionAngle = horizonPtr->frictionAngle * DEG_TO_RAD; // [rad] double tanAngle = tan(slopeAngle); double tanFrictionAngle = tan(frictionAngle); From 12809890b17cd298dbd60f6902ccfe07c4a00ced Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Fri, 19 Jul 2024 13:44:41 +0200 Subject: [PATCH 143/179] minor changes and added weight of stations to local proxy graph --- gis/gis.cpp | 93 +++++--------------------- gis/gis.h | 5 +- interpolation/interpolation.cpp | 39 ++++------- interpolation/interpolationConstants.h | 3 +- mathFunctions/furtherMathFunctions.cpp | 51 ++++---------- mathFunctions/furtherMathFunctions.h | 18 ++--- project/dialogInterpolation.cpp | 2 +- project/project.cpp | 4 +- proxyWidget/localProxyWidget.cpp | 66 ++++++++++++------ proxyWidget/localProxyWidget.h | 3 +- 10 files changed, 106 insertions(+), 178 deletions(-) diff --git a/gis/gis.cpp b/gis/gis.cpp index 934b6b56..6c965acf 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -287,13 +287,13 @@ namespace gis bool Crit3DRasterGrid::initializeParameters(const Crit3DRasterHeader& initHeader) { - parametersCell.clear(); - parametersCell.resize(initHeader.nrRows*initHeader.nrCols); - for (int i = 0; i < int(parametersCell.size()); i++) + singleCell.clear(); + singleCell.resize(initHeader.nrRows*initHeader.nrCols); + for (int i = 0; i < int(singleCell.size()); i++) { - parametersCell[i].row = i / initHeader.nrCols; - parametersCell[i].col = i % initHeader.nrCols; - parametersCell[i].fittingParameters.clear(); + singleCell[i].row = i / initHeader.nrCols; + singleCell[i].col = i % initHeader.nrCols; + singleCell[i].fittingParameters.clear(); } return true; @@ -301,12 +301,12 @@ namespace gis bool Crit3DRasterGrid::initializeParametersLatLonHeader(const Crit3DLatLonHeader& latLonHeader) { - parametersCell.resize(latLonHeader.nrRows*latLonHeader.nrCols); - for (int i = 0; i < int(parametersCell.size()); i++) + singleCell.resize(latLonHeader.nrRows*latLonHeader.nrCols); + for (int i = 0; i < int(singleCell.size()); i++) { - parametersCell[i].row = i / latLonHeader.nrCols; - parametersCell[i].col = i % latLonHeader.nrCols; - parametersCell[i].fittingParameters.clear(); + singleCell[i].row = i / latLonHeader.nrCols; + singleCell[i].col = i % latLonHeader.nrCols; + singleCell[i].fittingParameters.clear(); } return true; @@ -497,8 +497,8 @@ namespace gis int index = row * header->nrCols + col; - if (index < int(parametersCell.size())) - parameters = parametersCell[index].fittingParameters; + if (index < int(singleCell.size())) + parameters = singleCell[index].fittingParameters; return parameters; @@ -511,7 +511,7 @@ namespace gis return false; int index = row * header->nrCols + col; - parametersCell[index].fittingParameters = parameters; + singleCell[index].fittingParameters = parameters; return true; } @@ -542,7 +542,7 @@ namespace gis for (m = col-1; m < col+2; m++) { index = l * header->nrCols + m; - if (index >= 0 && index < int(parametersCell.size()) && (parametersCell[index].fittingParameters.size() > i && !parametersCell[index].fittingParameters[i].empty()) && (l != row || m !=col)) { + if (index >= 0 && index < int(singleCell.size()) && (singleCell[index].fittingParameters.size() > i && !singleCell[index].fittingParameters[i].empty()) && (l != row || m !=col)) { findFirst = 1; } if (findFirst==1) break; @@ -555,7 +555,7 @@ namespace gis //you're on a specific proxy rn. cycle through the cells, calculate the avg avg.clear(); - avg.resize(parametersCell[index].fittingParameters[i].size()); + avg.resize(singleCell[index].fittingParameters[i].size()); counter = 0; for (k = l; k < row+2; k++) @@ -563,10 +563,10 @@ namespace gis for (p = m; p < col+2; p++) { index = k * header->nrCols + p; - if (index >= 0 && index < int(parametersCell.size()) && parametersCell[index].fittingParameters.size() > i && !parametersCell[index].fittingParameters[i].empty()) { + if (index >= 0 && index < int(singleCell.size()) && singleCell[index].fittingParameters.size() > i && !singleCell[index].fittingParameters[i].empty()) { for (unsigned int o = 0; o < avg.size(); o++) { - avg[o] += parametersCell[index].fittingParameters[i][o]; + avg[o] += singleCell[index].fittingParameters[i][o]; } counter++; @@ -583,63 +583,6 @@ namespace gis return tempProxyVector; } - std::vector> Crit3DRasterGrid::prepareParametersOld(int row, int col, unsigned int activeProxyNr) - { - std::vector> tempProxyVector; - std::vector tempParVector; - tempProxyVector.clear(); - tempParVector.clear(); - double avg; - int counter; - int l, i, j, k; - int index; - bool findFirst = 0; - - if (isOutOfGrid(row, col)) - return tempProxyVector; - - //look for the first cell that has data in it. if there isn't any, return empty vector - for (i = row-1; i < row+2; i++) - { - for (j = col-1; j < col+2; j++) - { - index = i * header->nrCols + j; - if (index >= 0 && index < int(parametersCell.size()) && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) - findFirst = 1; - if (findFirst==1) break; - } - if (findFirst==1) break; - } - - for (k = 0; k < int(parametersCell[index].fittingParameters.size()); k++) - { - for (l = 0; l < int(parametersCell[index].fittingParameters[k].size()); l++) - { - avg = 0; - counter = 0; - for (int h = i; h < row+2; h++) - { - for (int m = j; m < col+2; m++) - { - index = h * header->nrCols + m; - if (index >= 0 && index < int(parametersCell.size()) && (parametersCell[index].fittingParameters.size() == activeProxyNr) && (i != row || j !=col)) - { - avg += parametersCell[index].fittingParameters[k][l]; - counter++; - } - } - } - tempParVector.push_back(avg/counter); - index = i*header->nrCols+j; - } - tempProxyVector.push_back(tempParVector); - tempParVector.clear(); - } - - return tempProxyVector; - - } - void convertFlagToNodata(Crit3DRasterGrid& myGrid) { if (myGrid.header->flag == NODATA) diff --git a/gis/gis.h b/gis/gis.h index 547aac3d..3031546e 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -139,7 +139,7 @@ Crit3DRasterCell(); }; - struct RasterGridParameters { + struct RasterGridCell { public: int row; int col; @@ -155,7 +155,7 @@ float minimum, maximum; bool isLoaded; Crit3DTime mapTime; - std::vector parametersCell; + std::vector singleCell; Crit3DUtmPoint* utmPoint(int myRow, int myCol); void getXY(int myRow, int myCol, double &x, double &y) const; @@ -192,7 +192,6 @@ std::vector> getParametersFromRowCol(int row, int col); bool setParametersForRowCol(int row, int col, std::vector> parameters); std::vector> prepareParameters(int row, int col, std::vector activeList); - std::vector> prepareParametersOld(int row, int col, unsigned int activeProxyNr); Crit3DTime getMapTime() const; void setMapTime(const Crit3DTime &value); diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 0b91d694..171adda9 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1033,7 +1033,7 @@ void localSelection(vector &inputPoints, vector < inputPoints[i].distance = gis::computeDistance(x, y, float((inputPoints[i]).point->utm.x), float((inputPoints[i]).point->utm.y)); unsigned int nrValid = 0; - float stepRadius = 5000; // [m] + float stepRadius = 2500; // [m] float r0 = 0; // [m] float r1 = stepRadius; // [m] unsigned int i; @@ -1077,7 +1077,6 @@ void localSelection(vector &inputPoints, vector < mySettings.setLocalRadius(float(maxDistance)); } - bool checkPrecipitationZero(const std::vector &myPoints, float precThreshold, int &nrNotNull) { nrNotNull = 0; @@ -1448,22 +1447,17 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati if (mySettings->getChosenElevationFunction() == piecewiseTwo) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); - tempParam = {-200, min-2, 0.002, -0.01, 5000, max+2, 0.01, 0.0015}; + tempParam = {-200, min-2, 0.002, -0.01, 5000, max+2, 0.01, -0.0015}; } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); - tempParam = {-200, min-2, 300, 0.002, -0.01, -0.01, 5000, max+2, 1000, 0.007, 0.0015, 0.0015}; + tempParam = {-200, min-2, 300, 0.002, -0.01, -0.01, 5000, max+2, 1000, 0.007, -0.0015, -0.0015}; } else if (mySettings->getChosenElevationFunction() == piecewiseThree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - tempParam = {-200, min-2, 300, 0.002, -0.01, 5000, max+2, 1000, 0.007, 0.0015}; - } - else if (mySettings->getChosenElevationFunction() == freiFree) - { - mySettings->getProxy(i)->setFittingFunctionName(freiFree); - tempParam = {min, 0, -4, -200, 0.1, 0.002, max+10, 0.006, 4, 5000, 1000, 0.006}; + tempParam = {-200, min-2, 300, 0.002, -0.01, 5000, max+2, 1000, 0.007, -0.0015}; } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } @@ -1504,11 +1498,9 @@ bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3 if (mySettings->getChosenElevationFunction() == piecewiseTwo) myFunc[i] = lapseRatePiecewise_two; else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) - myFunc[i] = lapseRatePiecewiseFree; + myFunc[i] = lapseRatePiecewise_three_free; else if (mySettings->getChosenElevationFunction() == piecewiseThree) - myFunc[i] = lapseRatePiecewiseThree_withSlope; - else if (mySettings->getChosenElevationFunction() == freiFree) - myFunc[i] = lapseRateFreiFree; + myFunc[i] = lapseRatePiecewise_three; else { errorStr = "Missing or wrong fitting function for proxy: " + mySettings->getProxy(i)->getName(); @@ -1581,25 +1573,18 @@ bool setAllFittingParameters(Crit3DProxyCombination myCombination, Crit3DInterpo } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { - myFunc.push_back(lapseRatePiecewiseFree); + myFunc.push_back(lapseRatePiecewise_three_free); mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 100, 0.001, -0.006, -0.006, 1800, max+2, 1000, 0.01, 0, 0}; } else if (mySettings->getChosenElevationFunction() == piecewiseThree) { - myFunc.push_back(lapseRatePiecewiseThree_withSlope); + myFunc.push_back(lapseRatePiecewise_three); mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) tempParam = {-200, min-2, 100, 0.002, -0.006, 1800, max+2, 1000, 0.01, 0}; } - else if (mySettings->getChosenElevationFunction() == freiFree) - { - myFunc.push_back(lapseRateFreiFree); - mySettings->getProxy(i)->setFittingFunctionName(freiFree); - if (!(mySettings->getProxy(i)->getFittingParametersRange().empty())) - tempParam = {min, 0, -4, -200, 0.1, 0, max+10, 0.006, 4, 1800, 1000, 0.006}; - } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } else @@ -1882,12 +1867,12 @@ bool multipleDetrendingElevation(Crit3DProxyCombination elevationCombination, st mySettings->setSingleFittingFunction(detrendingLapseRatePiecewise_two, elevationPos); } else if (mySettings->getProxy(elevationPos)->getFittingFunctionName() == piecewiseThreeFree) { - myFunc[elevationPos] = detrendingLapseRatePiecewiseFree; - mySettings->setSingleFittingFunction(detrendingLapseRatePiecewiseFree, elevationPos); + myFunc[elevationPos] = detrendingLapseRatePiecewise_three_free; + mySettings->setSingleFittingFunction(detrendingLapseRatePiecewise_three_free, elevationPos); } else if (mySettings->getProxy(elevationPos)->getFittingFunctionName() == piecewiseThree) { - myFunc[elevationPos] = detrendingLapseRatePiecewiseThree_withSlope; - mySettings->setSingleFittingFunction(detrendingLapseRatePiecewiseThree_withSlope, elevationPos); + myFunc[elevationPos] = detrendingLapseRatePiecewise_three; + mySettings->setSingleFittingFunction(detrendingLapseRatePiecewise_three, elevationPos); } func = myFunc[elevationPos].target&)>();; diff --git a/interpolation/interpolationConstants.h b/interpolation/interpolationConstants.h index 5cb13de0..c6b3013a 100644 --- a/interpolation/interpolationConstants.h +++ b/interpolation/interpolationConstants.h @@ -38,13 +38,12 @@ { "water_index", proxyWaterIndex} }; - enum TFittingFunction { piecewiseTwo, piecewiseThreeFree, piecewiseThree, freiFree, linear, noFunction }; + enum TFittingFunction { piecewiseTwo, piecewiseThreeFree, piecewiseThree, linear, noFunction }; const std::map fittingFunctionNames = { { "piecewise_two", piecewiseTwo }, { "free_triple_piecewise", piecewiseThreeFree}, { "triple_piecewise", piecewiseThree}, - { "Nonlinear Frei function (6 parameters)", freiFree }, { "linear", linear } }; diff --git a/mathFunctions/furtherMathFunctions.cpp b/mathFunctions/furtherMathFunctions.cpp index d85a3e29..a85d650f 100644 --- a/mathFunctions/furtherMathFunctions.cpp +++ b/mathFunctions/furtherMathFunctions.cpp @@ -69,33 +69,8 @@ double lapseRateFrei(double x, std::vector & par) return y - 0.5*par[2]*(1 + cos(PI*(x-par[3])/(par[4]))); } -double lapseRateFreiFree(double x, std::vector & par) -{ - /* - par[0] = T0; - par[1] = gamma1; - par[2] = a; - par[3] = h0; - par[4] = h1-h0; - par[5] = gamma2 - */ - - if (par.size() < 6) return NODATA; - double h1 = par[3]+par[4]; - if (x <= par[3]) - { - return par[0] - par[1]*x - par[2]; - } - else if (x >= (par[4]+par[3])) - { - return par[0] - par[5]*x; - } - return par[0] - ((par[5]*par[3]+par[1]*h1)/(par[3]+h1))*x - 0.5*par[2]*(1 + cos(PI*(x-par[3])/(par[4]))); -} - - -double lapseRatePiecewise_three(double x, std::vector & par) +double lapseRatePiecewise_three_noSlope(double x, std::vector & par) { // the piecewise line is parameterized as follows // the line passes through A(par[0];par[1])and B(par[0]+par[2];par[3]). par[4] is the slope of the 2 externals pieces @@ -124,7 +99,7 @@ double lapseRatePiecewise_three(double x, std::vector & par) } -double lapseRatePiecewiseThree_withSlope(double x, std::vector & par) +double lapseRatePiecewise_three(double x, std::vector & par) { //xa (par[0],par[1]), xb-xa = par[2], par[3] is the slope of the middle piece, //par[4] the slope of the first and last piece @@ -139,7 +114,7 @@ double lapseRatePiecewiseThree_withSlope(double x, std::vector & par) return par[3]*x - par[3]*par[0]+par[1]; } -double detrendingLapseRatePiecewiseThree_withSlope(double x, std::vector & par) +double detrendingLapseRatePiecewise_three(double x, std::vector & par) { //xa (par[0],par[1]), xb-xa = par[2], par[3] is the slope of the middle piece, //par[4] the slope of the first and last piece @@ -154,7 +129,7 @@ double detrendingLapseRatePiecewiseThree_withSlope(double x, std::vector & par) +double lapseRatePiecewise_three_free(double x, std::vector & par) { // the piecewise line is parameterized as follows // the line passes through A(par[0];par[1])and B(par[0]+par[2];...) @@ -186,7 +161,7 @@ double lapseRatePiecewiseFree(double x, std::vector & par) } } -double detrendingLapseRatePiecewiseFree(double x, std::vector & par) +double detrendingLapseRatePiecewise_three_free(double x, std::vector & par) { // the piecewise line is parameterized as follows // the line passes through A(par[0];par[1])and B(par[0]+par[2];...) @@ -1346,7 +1321,7 @@ namespace interpolation //grigliato const int numSteps = 20; - std::vector steps = {2*(parametersMax[0][0]-parametersMin[0][0])/numSteps, 2*(parametersMax[0][1]-parametersMin[0][1])/numSteps}; + std::vector stepSize = {2*(parametersMax[0][0]-parametersMin[0][0])/numSteps, 2*(parametersMax[0][1]-parametersMin[0][1])/numSteps}; int directions[] = {1, -1}; std::vector> firstGuessParam = parameters; @@ -1405,9 +1380,9 @@ namespace interpolation if (parameters.size() > proxyIndex && !parameters[proxyIndex].empty()) { if (dir == 0) - parameters[proxyIndex][paramIndex] = MINVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * steps[paramIndex], parametersMax[proxyIndex][paramIndex]); + parameters[proxyIndex][paramIndex] = MINVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * stepSize[paramIndex], parametersMax[proxyIndex][paramIndex]); else - parameters[proxyIndex][paramIndex] = MAXVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * steps[paramIndex], parametersMin[proxyIndex][paramIndex]); + parameters[proxyIndex][paramIndex] = MAXVALUE(firstGuessParam[proxyIndex][paramIndex] + directions[dir] * step * stepSize[paramIndex], parametersMin[proxyIndex][paramIndex]); } if ((counter > nrTrials) || ((R2Previous[0] != NODATA) && fabs(R2Previous[0]-R2Previous[nrMinima-1]) < deltaR2 )) @@ -2068,12 +2043,12 @@ namespace interpolation int counter = 0; //grigliato - std::vector steps; + std::vector stepSize; const int numSteps = 30; if (parameters.size() == 4) - steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 2*(parametersMax[2]-parametersMin[2])/numSteps, 2*(parametersMax[3]-parametersMin[3])/numSteps}; + stepSize = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 20*(parametersMax[2]-parametersMin[2])/numSteps, 20*(parametersMax[3]-parametersMin[3])/numSteps}; else if (parameters.size() == 6) - steps = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 4*(parametersMax[2]-parametersMin[2])/numSteps, 20*(parametersMax[3]-parametersMin[3])/numSteps,20*(parametersMax[3]-parametersMin[3])/numSteps,20*(parametersMax[3]-parametersMin[3])/numSteps }; + stepSize = {2*(parametersMax[0]-parametersMin[0])/numSteps, 2*(parametersMax[1]-parametersMin[1])/numSteps, 4*(parametersMax[2]-parametersMin[2])/numSteps, 20*(parametersMax[3]-parametersMin[3])/numSteps,20*(parametersMax[3]-parametersMin[3])/numSteps,20*(parametersMax[3]-parametersMin[3])/numSteps }; else return false; int directions[] = {1, -1}; @@ -2122,9 +2097,9 @@ namespace interpolation counter++; if (dir == 0) - parameters[paramIndex] = MINVALUE(firstGuessParam[paramIndex] + directions[dir] * step * steps[paramIndex], parametersMax[paramIndex]); + parameters[paramIndex] = MINVALUE(firstGuessParam[paramIndex] + directions[dir] * step * stepSize[paramIndex], parametersMax[paramIndex]); else - parameters[paramIndex] = MAXVALUE(firstGuessParam[paramIndex] + directions[dir] * step * steps[paramIndex], parametersMin[paramIndex]); + parameters[paramIndex] = MAXVALUE(firstGuessParam[paramIndex] + directions[dir] * step * stepSize[paramIndex], parametersMin[paramIndex]); } } diff --git a/mathFunctions/furtherMathFunctions.h b/mathFunctions/furtherMathFunctions.h index c5a3fc5b..0b9aa663 100644 --- a/mathFunctions/furtherMathFunctions.h +++ b/mathFunctions/furtherMathFunctions.h @@ -50,18 +50,20 @@ enum estimatedFunction {FUNCTION_CODE_SPHERICAL, FUNCTION_CODE_LINEAR, FUNCTION_ double functionLinear(double x, std::vector & par); double functionLinear_intercept(double x, std::vector & par); double multilinear(std::vector &x, std::vector &par); - double lapseRatePiecewise_three(double x, std::vector & par); - double lapseRatePiecewiseForInterpolation(double x, std::vector & par); - double lapseRatePiecewiseFree(double x, std::vector & par); - double detrendingLapseRatePiecewiseFree(double x, std::vector & par); - double lapseRatePiecewiseThree_withSlope(double x, std::vector & par); - double detrendingLapseRatePiecewiseThree_withSlope(double x, std::vector & par); - double lapseRatePiecewise_two(double x, std::vector & par); - double detrendingLapseRatePiecewise_two(double x, std::vector & par); double lapseRateFrei(double x, std::vector & par); double lapseRateFreiFree(double x, std::vector & par); double lapseRateRotatedSigmoid(double x, std::vector par); + double lapseRatePiecewise_two(double x, std::vector & par); + double lapseRatePiecewise_three_noSlope(double x, std::vector & par); + double lapseRatePiecewise_three(double x, std::vector & par); + double lapseRatePiecewise_three_free(double x, std::vector & par); + + double detrendingLapseRatePiecewise_two(double x, std::vector & par); + double detrendingLapseRatePiecewise_three(double x, std::vector & par); + double detrendingLapseRatePiecewise_three_free(double x, std::vector & par); + + namespace integration { float trapzdParametric(float (*func)(TfunctionInput), int nrPar, float *par , float a , float b , int n); diff --git a/project/dialogInterpolation.cpp b/project/dialogInterpolation.cpp index 11ae05a7..b78bd227 100644 --- a/project/dialogInterpolation.cpp +++ b/project/dialogInterpolation.cpp @@ -142,7 +142,7 @@ DialogInterpolation::DialogInterpolation(Project *myProject) std::map::const_iterator itElFunc; for (itElFunc = fittingFunctionNames.begin(); itElFunc != fittingFunctionNames.end(); ++itElFunc) { - if (itElFunc->first == "linear" || itElFunc->first == "Nonlinear Frei function (6 parameters)") + if (itElFunc->first == "linear") continue; elevationFunctionEdit.addItem(QString::fromStdString(itElFunc->first), QString::fromStdString(itElFunc->first)); } diff --git a/project/project.cpp b/project/project.cpp index 15f17228..1b138424 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -3702,12 +3702,12 @@ void Project::showLocalProxyGraph(gis::Crit3DGeoPoint myPoint, gis::Crit3DRaster int row, col; std::vector> parameters; - if (myDataRaster->isLoaded && !myDataRaster->parametersCell.empty()) + if (myDataRaster->isLoaded && !myDataRaster->singleCell.empty()) { gis::getRowColFromXY(*(myDataRaster->header), myUtm, &row, &col); parameters = myDataRaster->getParametersFromRowCol(row, col); } - if (this->meteoGridLoaded && !this->meteoGridDbHandler->meteoGrid()->dataMeteoGrid.parametersCell.empty()) + if (this->meteoGridLoaded && !this->meteoGridDbHandler->meteoGrid()->dataMeteoGrid.singleCell.empty()) { gis::getGridRowColFromXY(meteoGridDbHandler->meteoGrid()->gridStructure().header(), myPoint.longitude, myPoint.latitude, &row, &col); parameters = meteoGridDbHandler->meteoGrid()->dataMeteoGrid.getParametersFromRowCol(row, col); diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 77af178b..607b6c2a 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -62,6 +62,7 @@ Crit3DLocalProxyWidget::Crit3DLocalProxyWidget(double x, double y, std::vectoraddWidget(&detrended); selectionOptionBoxLayout->addWidget(&modelLR); selectionOptionBoxLayout->addWidget(&climatologicalLR); + selectionOptionBoxLayout->addWidget(&stationWeights); selectionOptionEditLayout->addWidget(r2Label); selectionOptionEditLayout->addWidget(&r2); @@ -140,25 +142,7 @@ Crit3DLocalProxyWidget::Crit3DLocalProxyWidget(double x, double y, std::vectoraddStretch(30); selectionLayout->addLayout(selectionOptionLayout); - if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseThree && parameters[proxyPos].size() == 5) - { - QVBoxLayout *parametriLayout = new QVBoxLayout(); - - QLabel *H0Lab = new QLabel(QString("H0: %1").arg(parameters[proxyPos][0])); - QLabel *T0Lab = new QLabel(QString("T0: %1").arg(parameters[proxyPos][1])); - QLabel *H1Lab = new QLabel(QString("H1: %1").arg(parameters[proxyPos][0]+parameters[proxyPos][2])); - QLabel *T1Lab = new QLabel(QString("T1: %1").arg(parameters[proxyPos][1]+parameters[proxyPos][3])); - QLabel *slopeLab = new QLabel(QString("slope: %1").arg(parameters[proxyPos][4])); - - parametriLayout->addWidget(H0Lab); - parametriLayout->addWidget(T0Lab); - parametriLayout->addWidget(H1Lab); - parametriLayout->addWidget(T1Lab); - parametriLayout->addWidget(slopeLab); - - selectionLayout->addLayout(parametriLayout); - } - else if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseTwo && parameters[proxyPos].size() == 4) + if (!parameters.empty() && interpolationSettings->getProxy(proxyPos)->getFittingFunctionName() == piecewiseTwo && parameters[proxyPos].size() == 4) { QVBoxLayout *parametriLayout = new QVBoxLayout(); @@ -242,6 +226,7 @@ Crit3DLocalProxyWidget::Crit3DLocalProxyWidget(double x, double y, std::vectorclimatologicalLRClicked(toggled); }); connect(&modelLR, &QCheckBox::toggled, [=](int toggled){ this->modelLRClicked(toggled); }); connect(&detrended, &QCheckBox::toggled, [=](){ this->plot(); }); + connect(&stationWeights, &QCheckBox::toggled, [=] () {this->plot();}); connect(updateStations, &QAction::triggered, this, [=](){ this->plot(); }); if (currentFrequency != noFrequency) @@ -371,6 +356,14 @@ void Crit3DLocalProxyWidget::plot() outInterpolationPoints.clear(); subsetInterpolationPoints.clear(); std::string errorStdStr; + + for (QGraphicsTextItem* label : weightLabels) + { + chartView->scene()->removeItem(label); + delete label; + } + weightLabels.clear(); + if (detrended.isChecked()) { outInterpolationPoints.clear(); @@ -485,6 +478,37 @@ void Crit3DLocalProxyWidget::plot() { modelLRClicked(1); } + + if (stationWeights.isChecked()) + { + QChart* chart = chartView->chart(); + QRectF chartRect = chart->plotArea(); + double xMin = chartView->axisX->min(); + double xMax = chartView->axisX->max(); + double yMin = chartView->axisY->min(); + double yMax = chartView->axisY->max(); + + for (int i = 0; i < int(subsetInterpolationPoints.size()); i++) + { + float proxyVal = subsetInterpolationPoints[i].getProxyValue(proxyPos); + float varValue = subsetInterpolationPoints[i].value; + + if (proxyVal != NODATA && varValue != NODATA) + { + double xRatio = (proxyVal - xMin) / (xMax - xMin); + double yRatio = (varValue - yMin) / (yMax - yMin); + + QPointF scenePos; + scenePos.setX(chartRect.left() + xRatio * chartRect.width()); + scenePos.setY(chartRect.bottom() - yRatio * chartRect.height()); + + QGraphicsTextItem* weightLabel = new QGraphicsTextItem(QString::number(subsetInterpolationPoints[i].regressionWeight)); + weightLabel->setPos(scenePos); + chartView->scene()->addItem(weightLabel); + weightLabels.push_back(weightLabel); + } + } + } } @@ -544,7 +568,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) for (int p = 0; p < int(xVector.size()); p++) { point.setX(xVector[p]); - point.setY(lapseRatePiecewiseThree_withSlope(xVector[p], parameters[proxyPos])); + point.setY(lapseRatePiecewise_three(xVector[p], parameters[proxyPos])); point_vector.append(point); } } @@ -581,7 +605,7 @@ void Crit3DLocalProxyWidget::modelLRClicked(int toggled) for (int p = 0; p < int(xVector.size()); p++) { point.setX(xVector[p]); - point.setY(lapseRatePiecewiseFree(xVector[p], parameters[proxyPos])); + point.setY(lapseRatePiecewise_three_free(xVector[p], parameters[proxyPos])); point_vector.append(point); } diff --git a/proxyWidget/localProxyWidget.h b/proxyWidget/localProxyWidget.h index cb62df4f..63a291ba 100644 --- a/proxyWidget/localProxyWidget.h +++ b/proxyWidget/localProxyWidget.h @@ -23,7 +23,6 @@ class Crit3DLocalProxyWidget : public QWidget void plot(); void climatologicalLRClicked(int toggled); void modelLRClicked(int toggled); - private: double x; double y; @@ -49,11 +48,13 @@ class Crit3DLocalProxyWidget : public QWidget QCheckBox detrended; QCheckBox climatologicalLR; QCheckBox modelLR; + QCheckBox stationWeights; QTextEdit r2; QTextEdit lapseRate; ChartView *chartView; meteoVariable myVar; int proxyPos; + std::vector weightLabels; Crit3DTime getCurrentTime(); From b25b645ce7818fc7936079113b668abba1ab591a Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Fri, 19 Jul 2024 15:25:03 +0200 Subject: [PATCH 144/179] added new local selection function --- interpolation/interpolation.cpp | 61 ++++++++++++++++++++++++++++++++ interpolation/interpolation.h | 3 ++ project/project.cpp | 2 +- proxyWidget/localProxyWidget.cpp | 4 +-- 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 171adda9..9f758369 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1015,6 +1015,67 @@ float gaussWeighted(vector &myPointList) } */ +void localSelection_new(std::vector &inputPoints, std::vector &selectedPoints, + float x, float y, float z, Crit3DInterpolationSettings& mySettings) +{ + std::vector tempPoints; + unsigned int i; + float radius; + unsigned int nrValid = 0; + int minPoints = mySettings.getMinPointsLocalDetrending()*1.2; + float shepardInitialRadius = computeShepardInitialRadius(mySettings.getPointsBoundingBoxArea(), unsigned(inputPoints.size()), minPoints); + + // define a first neighborhood inside initial radius + for (i=0; i < inputPoints.size(); i++) + { + inputPoints[i].distance = gis::computeDistance(x, y, float((inputPoints[i]).point->utm.x), float((inputPoints[i]).point->utm.y)); + if (inputPoints[i].distance <= shepardInitialRadius && + inputPoints[i].distance > 0 && + checkLapseRateCode(inputPoints[i].lapseRateCode, mySettings.getUseLapseRateCode(), true)) + { + tempPoints.push_back(inputPoints[i]); + nrValid++; + } + } + + if (tempPoints.size() <= minPoints) + { + nrValid = sortPointsByDistance(minPoints + 1, inputPoints, selectedPoints); + if (nrValid > minPoints) + { + radius = selectedPoints[minPoints].distance; + selectedPoints.pop_back(); + } + else + radius = selectedPoints[nrValid-1].distance + float(EPSILON); + } + else if (tempPoints.size() > minPoints) + { + nrValid = sortPointsByDistance(minPoints + 1, tempPoints, selectedPoints); + radius = selectedPoints[minPoints].distance; + selectedPoints.pop_back(); + } + else + { + selectedPoints = tempPoints; + radius = shepardInitialRadius; + } + + for (int i = 0; i < selectedPoints.size(); i++) + { + selectedPoints[i].regressionWeight = MAXVALUE((-(1/std::pow(radius,4)*(std::pow(selectedPoints[i].distance,4)))+1),EPSILON); + //selectedPoints[i].regressionWeight = 1; + //selectedPoints[i].heightWeight = 1./((2./maxHeightDelta)*selectedPoints[i].point->z+1); + selectedPoints[i].heightWeight = 1; + } + mySettings.setLocalRadius(float(radius)); + + return; +} + + + + // TODO elevation std dev? void localSelection(vector &inputPoints, vector &selectedPoints, float x, float y, float z, Crit3DInterpolationSettings& mySettings) diff --git a/interpolation/interpolation.h b/interpolation/interpolation.h index 013a12f0..f4857765 100644 --- a/interpolation/interpolation.h +++ b/interpolation/interpolation.h @@ -100,6 +100,9 @@ std::vector &selectedPoints, float x, float y, float z, Crit3DInterpolationSettings &mySettings); + void localSelection_new(std::vector &inputPoints, std::vector &selectedPoints, + float x, float y, float z, Crit3DInterpolationSettings& mySettings); + bool proxyValidity(std::vector &myPoints, int proxyPos, float stdDevThreshold, double &avg, double &stdDev); diff --git a/project/project.cpp b/project/project.cpp index b2013d98..70b6a70f 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2447,7 +2447,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT if (! getProxyValuesXY(x, y, &interpolationSettings, proxyValues)) interpolationSettings.setProxiesComplete(false); std::vector subsetInterpolationPoints; - localSelection(interpolationPoints, subsetInterpolationPoints, x, y, z, interpolationSettings); + localSelection_new(interpolationPoints, subsetInterpolationPoints, x, y, z, interpolationSettings); if (interpolationSettings.getUseLocalDetrending()) interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col, myCombination.getActiveList())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 607b6c2a..8cd4dadd 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -372,7 +372,7 @@ void Crit3DLocalProxyWidget::plot() interpolationSettings, meteoSettings, climateParam, outInterpolationPoints, checkSpatialQuality, errorStdStr); - localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); + localSelection_new(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); detrending(subsetInterpolationPoints, interpolationSettings->getSelectedCombination(), interpolationSettings, climateParam, myVar, getCurrentTime()); } else @@ -380,7 +380,7 @@ void Crit3DLocalProxyWidget::plot() checkAndPassDataToInterpolation(quality, myVar, meteoPoints, nrMeteoPoints, getCurrentTime(), SQinterpolationSettings, interpolationSettings, meteoSettings, climateParam, outInterpolationPoints, checkSpatialQuality, errorStdStr); - localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); + localSelection_new(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); } QList pointListPrimary, pointListSecondary, pointListSupplemental, pointListMarked; QMap< QString, QPointF > idPointMap1; From 895c26814f59548dc07cb4f786019bca5aa3d985 Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Fri, 19 Jul 2024 15:29:09 +0200 Subject: [PATCH 145/179] changed function call --- project/project.cpp | 2 +- proxyWidget/localProxyWidget.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 70b6a70f..b2013d98 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2447,7 +2447,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT if (! getProxyValuesXY(x, y, &interpolationSettings, proxyValues)) interpolationSettings.setProxiesComplete(false); std::vector subsetInterpolationPoints; - localSelection_new(interpolationPoints, subsetInterpolationPoints, x, y, z, interpolationSettings); + localSelection(interpolationPoints, subsetInterpolationPoints, x, y, z, interpolationSettings); if (interpolationSettings.getUseLocalDetrending()) interpolationSettings.setFittingParameters(myRaster->prepareParameters(row, col, myCombination.getActiveList())); if (! preInterpolation(subsetInterpolationPoints, &interpolationSettings, meteoSettings, &climateParameters, diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 8cd4dadd..607b6c2a 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -372,7 +372,7 @@ void Crit3DLocalProxyWidget::plot() interpolationSettings, meteoSettings, climateParam, outInterpolationPoints, checkSpatialQuality, errorStdStr); - localSelection_new(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); + localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); detrending(subsetInterpolationPoints, interpolationSettings->getSelectedCombination(), interpolationSettings, climateParam, myVar, getCurrentTime()); } else @@ -380,7 +380,7 @@ void Crit3DLocalProxyWidget::plot() checkAndPassDataToInterpolation(quality, myVar, meteoPoints, nrMeteoPoints, getCurrentTime(), SQinterpolationSettings, interpolationSettings, meteoSettings, climateParam, outInterpolationPoints, checkSpatialQuality, errorStdStr); - localSelection_new(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); + localSelection(outInterpolationPoints, subsetInterpolationPoints, x, y, z, *interpolationSettings); } QList pointListPrimary, pointListSecondary, pointListSupplemental, pointListMarked; QMap< QString, QPointF > idPointMap1; From 71c8454aadedded07d6a8b1050d3ad87df9675e9 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 19 Jul 2024 16:32:37 +0200 Subject: [PATCH 146/179] update 3D --- interpolation/interpolation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index 9f758369..acb95b2c 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1022,7 +1022,7 @@ void localSelection_new(std::vector &inputPoints, unsigned int i; float radius; unsigned int nrValid = 0; - int minPoints = mySettings.getMinPointsLocalDetrending()*1.2; + unsigned int minPoints = unsigned(mySettings.getMinPointsLocalDetrending() * 1.2); float shepardInitialRadius = computeShepardInitialRadius(mySettings.getPointsBoundingBoxArea(), unsigned(inputPoints.size()), minPoints); // define a first neighborhood inside initial radius From 4e10a9514b1a5a12884a5c5b66591cdf57a061b1 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 19 Jul 2024 17:48:20 +0200 Subject: [PATCH 147/179] update change axis --- commonChartElements/dialogChangeAxis.cpp | 53 ++++++++++++++----- commonChartElements/dialogChangeAxis.h | 10 +++- homogeneityWidget/homogeneityWidget.cpp | 2 +- meteoWidget/meteoWidget.cpp | 4 +- .../pointStatisticsWidget.cpp | 2 +- synchronicityWidget/synchronicityWidget.cpp | 4 +- waterTable/waterTableChartView.cpp | 2 +- waterTable/waterTableChartView.h | 8 +-- waterTable/waterTableWidget.cpp | 31 +++++++---- waterTable/waterTableWidget.h | 11 ++-- 10 files changed, 89 insertions(+), 38 deletions(-) diff --git a/commonChartElements/dialogChangeAxis.cpp b/commonChartElements/dialogChangeAxis.cpp index 6fd91e0b..e3bcd5d9 100644 --- a/commonChartElements/dialogChangeAxis.cpp +++ b/commonChartElements/dialogChangeAxis.cpp @@ -1,18 +1,22 @@ #include "dialogChangeAxis.h" -DialogChangeAxis::DialogChangeAxis(bool isLeftAxis_) +DialogChangeAxis::DialogChangeAxis(int nrAxis, bool isDate) { - isLeftAxis = isLeftAxis_; QString title; - if (isLeftAxis) + if (nrAxis == 0) + { + title = "Change X Axis"; + } + else if (nrAxis == 1) { title = "Change Left Axis"; } - else + else if (nrAxis == 2) { title = "Change Right Axis"; } this->setWindowTitle(title); + QVBoxLayout* mainLayout = new QVBoxLayout; this->resize(200, 100); @@ -20,17 +24,32 @@ DialogChangeAxis::DialogChangeAxis(bool isLeftAxis_) QHBoxLayout *layoutEdit = new QHBoxLayout; QLabel minValueLabel("Minimum value:"); - minValueLabel.setBuddy(&minVal); - minVal.setValidator(new QDoubleValidator(-999.0, 999.0, 3)); + layoutEdit->addWidget(&minValueLabel); + if (isDate) + { + minValueLabel.setBuddy(&minDate); + layoutEdit->addWidget(&minDate); + } + else + { + minValueLabel.setBuddy(&minVal); + minVal.setValidator(new QDoubleValidator(-9999.0, 9999.0, 3)); + layoutEdit->addWidget(&minVal); + } QLabel maxValueLabel("Maximum value:"); - maxValueLabel.setBuddy(&maxVal); - maxVal.setValidator(new QDoubleValidator(-999.0, 999.0, 3)); - - layoutEdit->addWidget(&minValueLabel); - layoutEdit->addWidget(&minVal); layoutEdit->addWidget(&maxValueLabel); - layoutEdit->addWidget(&maxVal); + if (isDate) + { + minValueLabel.setBuddy(&maxDate); + layoutEdit->addWidget(&maxDate); + } + else + { + maxValueLabel.setBuddy(&maxVal); + maxVal.setValidator(new QDoubleValidator(-9999.0, 9999.0, 3)); + layoutEdit->addWidget(&maxVal); + } QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); @@ -84,3 +103,13 @@ float DialogChangeAxis::getMaxVal() const { return maxVal.text().toFloat(); } + +QDate DialogChangeAxis::getMinDate() const +{ + return minDate.date(); +} + +QDate DialogChangeAxis::getMaxDate() const +{ + return maxDate.date(); +} diff --git a/commonChartElements/dialogChangeAxis.h b/commonChartElements/dialogChangeAxis.h index a6339371..f3ccb81a 100644 --- a/commonChartElements/dialogChangeAxis.h +++ b/commonChartElements/dialogChangeAxis.h @@ -8,16 +8,22 @@ Q_OBJECT private: - bool isLeftAxis; + QDateEdit minDate; QLineEdit minVal; + + QDateEdit maxDate; QLineEdit maxVal; public: - DialogChangeAxis(bool isLeftAxis); + DialogChangeAxis(int nrAxis, bool isDate); ~DialogChangeAxis() override; void done(bool res); + float getMinVal() const; float getMaxVal() const; + + QDate getMinDate() const; + QDate getMaxDate() const; }; #endif // DIALOGCHANGEAXIS_H diff --git a/homogeneityWidget/homogeneityWidget.cpp b/homogeneityWidget/homogeneityWidget.cpp index 7fdc71b6..690b20b6 100644 --- a/homogeneityWidget/homogeneityWidget.cpp +++ b/homogeneityWidget/homogeneityWidget.cpp @@ -565,7 +565,7 @@ void Crit3DHomogeneityWidget::updateYears() void Crit3DHomogeneityWidget::on_actionChangeLeftAxis() { - DialogChangeAxis changeAxisDialog(true); + DialogChangeAxis changeAxisDialog(1, false); if (changeAxisDialog.result() == QDialog::Accepted) { homogeneityChartView->setYmax(changeAxisDialog.getMaxVal()); diff --git a/meteoWidget/meteoWidget.cpp b/meteoWidget/meteoWidget.cpp index 20e0e43a..79d56abd 100644 --- a/meteoWidget/meteoWidget.cpp +++ b/meteoWidget/meteoWidget.cpp @@ -2999,7 +2999,7 @@ void Crit3DMeteoWidget::setIsEnsemble(bool value) void Crit3DMeteoWidget::on_actionChangeLeftAxis() { - DialogChangeAxis changeAxisDialog(true); + DialogChangeAxis changeAxisDialog(1, false); if (changeAxisDialog.result() == QDialog::Accepted) { axisY_sx->setMax(changeAxisDialog.getMaxVal()); @@ -3010,7 +3010,7 @@ void Crit3DMeteoWidget::on_actionChangeLeftAxis() void Crit3DMeteoWidget::on_actionChangeRightAxis() { - DialogChangeAxis changeAxisDialog(false); + DialogChangeAxis changeAxisDialog(2, false); if (changeAxisDialog.result() == QDialog::Accepted) { axisY_dx->setMax(changeAxisDialog.getMaxVal()); diff --git a/pointStatisticsWidget/pointStatisticsWidget.cpp b/pointStatisticsWidget/pointStatisticsWidget.cpp index 3a7fdbc5..2e7f70ae 100644 --- a/pointStatisticsWidget/pointStatisticsWidget.cpp +++ b/pointStatisticsWidget/pointStatisticsWidget.cpp @@ -1689,7 +1689,7 @@ void Crit3DPointStatisticsWidget::computePlot() void Crit3DPointStatisticsWidget::on_actionChangeLeftAxis() { - DialogChangeAxis changeAxisDialog(true); + DialogChangeAxis changeAxisDialog(1, false); if (changeAxisDialog.result() == QDialog::Accepted) { chartView->setYmax(changeAxisDialog.getMaxVal()); diff --git a/synchronicityWidget/synchronicityWidget.cpp b/synchronicityWidget/synchronicityWidget.cpp index 277f9d47..663ed37f 100644 --- a/synchronicityWidget/synchronicityWidget.cpp +++ b/synchronicityWidget/synchronicityWidget.cpp @@ -398,7 +398,7 @@ void Crit3DSynchronicityWidget::changeInterpolationDate() void Crit3DSynchronicityWidget::on_actionChangeLeftSynchAxis() { - DialogChangeAxis changeAxisDialog(true); + DialogChangeAxis changeAxisDialog(1, false); if (changeAxisDialog.result() == QDialog::Accepted) { synchronicityChartView->setYmax(changeAxisDialog.getMaxVal()); @@ -408,7 +408,7 @@ void Crit3DSynchronicityWidget::on_actionChangeLeftSynchAxis() void Crit3DSynchronicityWidget::on_actionChangeLeftInterpolationAxis() { - DialogChangeAxis changeAxisDialog(true); + DialogChangeAxis changeAxisDialog(1, false); if (changeAxisDialog.result() == QDialog::Accepted) { interpolationChartView->setYmax(changeAxisDialog.getMaxVal()); diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index 30891b63..b170abb6 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -32,7 +32,7 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : } -void WaterTableChartView::draw(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, +void WaterTableChartView::drawWaterTable(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, QMap obsDepths, float maximumObservedDepth) { axisY->setMax(maximumObservedDepth); // unit of observed watertable data, usually [cm] diff --git a/waterTable/waterTableChartView.h b/waterTable/waterTableChartView.h index 879bc998..3ca4b30b 100644 --- a/waterTable/waterTableChartView.h +++ b/waterTable/waterTableChartView.h @@ -11,20 +11,22 @@ public: WaterTableChartView(QWidget *parent = 0); - void draw(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, - QMap obsDepths, float maximumObservedDepth); + void drawWaterTable(std::vector &myDates, std::vector &myHindcastSeries, + std::vector &myInterpolateSeries, QMap obsDepths, + float maximumObservedDepth); void tooltipObsDepthSeries(QPointF point, bool state); void tooltipLineSeries(QPointF point, bool state); void handleMarkerClicked(); QList exportInterpolationValues(); + QDateTimeAxis* axisX; + private: QScatterSeries* obsDepthSeries; QLineSeries* hindcastSeries; QLineSeries* interpolationSeries; - QDateTimeAxis* axisX; QValueAxis* axisY; Callout *m_tooltip; }; diff --git a/waterTable/waterTableWidget.cpp b/waterTable/waterTableWidget.cpp index b8e4bec8..75694a56 100644 --- a/waterTable/waterTableWidget.cpp +++ b/waterTable/waterTableWidget.cpp @@ -1,4 +1,5 @@ #include "waterTableWidget.h" +#include "dialogChangeAxis.h" WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths, float maxObservedDepth) @@ -22,19 +23,36 @@ WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates menuBar->addMenu(editMenu); mainLayout->setMenuBar(menuBar); QAction* exportInterpolation = new QAction(tr("&Export interpolation as csv"), this); + QAction* changeXAxis = new QAction(tr("&Change period (X axis)"), this); editMenu->addAction(exportInterpolation); + editMenu->addAction(changeXAxis); mainLayout->addLayout(plotLayout); setLayout(mainLayout); connect(exportInterpolation, &QAction::triggered, this, &WaterTableWidget::on_actionExportInterpolationData); + connect(exportInterpolation, &QAction::triggered, this, &WaterTableWidget::on_actionChangeXAxis); - waterTableChartView->draw(myDates, myHindcastSeries, myInterpolateSeries, obsDepths, maxObservedDepth); + waterTableChartView->drawWaterTable(myDates, myHindcastSeries, myInterpolateSeries, obsDepths, maxObservedDepth); } -void WaterTableWidget::on_actionExportInterpolationData() + +void WaterTableWidget::on_actionChangeXAxis() { + DialogChangeAxis changeAxisDialog(0, true); + if (changeAxisDialog.result() == QDialog::Accepted) + { + QDateTime myDateTime; + myDateTime.setDate(changeAxisDialog.getMaxDate()); + waterTableChartView->axisX->setMax(myDateTime); + myDateTime.setDate(changeAxisDialog.getMinDate()); + waterTableChartView->axisX->setMin(myDateTime); + } +} + +void WaterTableWidget::on_actionExportInterpolationData() +{ QString csvFileName = QFileDialog::getSaveFileName(this, tr("Save current data"), "", tr("csv files (*.csv)")); if (csvFileName != "") { @@ -66,12 +84,3 @@ void WaterTableWidget::on_actionExportInterpolationData() } } -WaterTableWidget::~WaterTableWidget() -{ - -} - -void WaterTableWidget::closeEvent(QCloseEvent *event) -{ - event->accept(); -} diff --git a/waterTable/waterTableWidget.h b/waterTable/waterTableWidget.h index cb43494d..765de3fb 100644 --- a/waterTable/waterTableWidget.h +++ b/waterTable/waterTableWidget.h @@ -12,13 +12,18 @@ public: WaterTableWidget(const QString &id, std::vector myDates, std::vector myHindcastSeries, std::vector myInterpolateSeries, QMap obsDepths, float maxObservedDepth); - ~WaterTableWidget(); - void closeEvent(QCloseEvent *event); - void on_actionExportInterpolationData(); + + ~WaterTableWidget() { ; } + + void closeEvent(QCloseEvent *event) + { event->accept(); } private: WaterTableChartView *waterTableChartView; + void on_actionExportInterpolationData(); + void on_actionChangeXAxis(); + }; #endif // WATERTABLEWIDGET_H From 9a8b276f09393632bb7c7281ca2b8ee4971ab9b5 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 22 Jul 2024 13:31:11 +0200 Subject: [PATCH 148/179] update change axis --- commonChartElements/dialogChangeAxis.cpp | 32 +++++++++++++++++------- commonChartElements/dialogChangeAxis.h | 4 ++- waterTable/waterTableWidget.cpp | 17 +++++++------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/commonChartElements/dialogChangeAxis.cpp b/commonChartElements/dialogChangeAxis.cpp index e3bcd5d9..9a249643 100644 --- a/commonChartElements/dialogChangeAxis.cpp +++ b/commonChartElements/dialogChangeAxis.cpp @@ -1,7 +1,9 @@ #include "dialogChangeAxis.h" -DialogChangeAxis::DialogChangeAxis(int nrAxis, bool isDate) +DialogChangeAxis::DialogChangeAxis(int nrAxis, bool isDate_) { + isDateAxis = isDate_; + QString title; if (nrAxis == 0) { @@ -25,7 +27,7 @@ DialogChangeAxis::DialogChangeAxis(int nrAxis, bool isDate) QLabel minValueLabel("Minimum value:"); layoutEdit->addWidget(&minValueLabel); - if (isDate) + if (isDateAxis) { minValueLabel.setBuddy(&minDate); layoutEdit->addWidget(&minDate); @@ -39,7 +41,7 @@ DialogChangeAxis::DialogChangeAxis(int nrAxis, bool isDate) QLabel maxValueLabel("Maximum value:"); layoutEdit->addWidget(&maxValueLabel); - if (isDate) + if (isDateAxis) { minValueLabel.setBuddy(&maxDate); layoutEdit->addWidget(&maxDate); @@ -74,16 +76,28 @@ void DialogChangeAxis::done(bool res) { if (res) // ok { - if (minVal.text().isEmpty()) + if (isDateAxis) { - QMessageBox::information(nullptr, "Missing min value", "Insert min val"); - return; + if (minDate.date() >= maxDate.date()) + { + QMessageBox::warning(nullptr, "Wrong date", "Insert correct dates."); + return; + } } - if (maxVal.text().isEmpty()) + else { - QMessageBox::information(nullptr, "Missing max value", "Insert max val"); - return; + if (minVal.text().isEmpty()) + { + QMessageBox::warning(nullptr, "Missing min value", "Insert minimum value."); + return; + } + if (maxVal.text().isEmpty()) + { + QMessageBox::warning(nullptr, "Missing max value", "Insert maximum value."); + return; + } } + QDialog::done(QDialog::Accepted); return; } diff --git a/commonChartElements/dialogChangeAxis.h b/commonChartElements/dialogChangeAxis.h index f3ccb81a..bf230494 100644 --- a/commonChartElements/dialogChangeAxis.h +++ b/commonChartElements/dialogChangeAxis.h @@ -8,6 +8,8 @@ Q_OBJECT private: + bool isDateAxis; + QDateEdit minDate; QLineEdit minVal; @@ -15,7 +17,7 @@ QLineEdit maxVal; public: - DialogChangeAxis(int nrAxis, bool isDate); + DialogChangeAxis(int nrAxis, bool isDate_); ~DialogChangeAxis() override; void done(bool res); diff --git a/waterTable/waterTableWidget.cpp b/waterTable/waterTableWidget.cpp index 75694a56..e5a039f6 100644 --- a/waterTable/waterTableWidget.cpp +++ b/waterTable/waterTableWidget.cpp @@ -22,8 +22,8 @@ WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates menuBar->addMenu(editMenu); mainLayout->setMenuBar(menuBar); - QAction* exportInterpolation = new QAction(tr("&Export interpolation as csv"), this); - QAction* changeXAxis = new QAction(tr("&Change period (X axis)"), this); + QAction* exportInterpolation = new QAction(tr("&Export interpolation as csv.."), this); + QAction* changeXAxis = new QAction(tr("&Change period (X axis).."), this); editMenu->addAction(exportInterpolation); editMenu->addAction(changeXAxis); @@ -31,7 +31,7 @@ WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates setLayout(mainLayout); connect(exportInterpolation, &QAction::triggered, this, &WaterTableWidget::on_actionExportInterpolationData); - connect(exportInterpolation, &QAction::triggered, this, &WaterTableWidget::on_actionChangeXAxis); + connect(changeXAxis, &QAction::triggered, this, &WaterTableWidget::on_actionChangeXAxis); waterTableChartView->drawWaterTable(myDates, myHindcastSeries, myInterpolateSeries, obsDepths, maxObservedDepth); } @@ -40,13 +40,14 @@ WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates void WaterTableWidget::on_actionChangeXAxis() { DialogChangeAxis changeAxisDialog(0, true); + if (changeAxisDialog.result() == QDialog::Accepted) { - QDateTime myDateTime; - myDateTime.setDate(changeAxisDialog.getMaxDate()); - waterTableChartView->axisX->setMax(myDateTime); - myDateTime.setDate(changeAxisDialog.getMinDate()); - waterTableChartView->axisX->setMin(myDateTime); + QDateTime firstDate, lastDate; + firstDate.setDate(changeAxisDialog.getMinDate()); + lastDate.setDate(changeAxisDialog.getMaxDate()); + waterTableChartView->axisX->setRange(firstDate, lastDate); + waterTableChartView->update(); } } From 9f5a5f6b8b189c8de1af8bc01f782cbca0db628c Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 22 Jul 2024 13:40:58 +0200 Subject: [PATCH 149/179] update change axis --- commonChartElements/dialogChangeAxis.cpp | 2 +- waterTable/waterTableChartView.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/commonChartElements/dialogChangeAxis.cpp b/commonChartElements/dialogChangeAxis.cpp index 9a249643..c14f64fe 100644 --- a/commonChartElements/dialogChangeAxis.cpp +++ b/commonChartElements/dialogChangeAxis.cpp @@ -80,7 +80,7 @@ void DialogChangeAxis::done(bool res) { if (minDate.date() >= maxDate.date()) { - QMessageBox::warning(nullptr, "Wrong date", "Insert correct dates."); + QMessageBox::warning(nullptr, "Wrong dates!", "Insert correct dates."); return; } } diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index b170abb6..4fda16c9 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -5,12 +5,12 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : { obsDepthSeries = new QScatterSeries(); obsDepthSeries->setName("Observed"); - obsDepthSeries->setColor(Qt::green); + obsDepthSeries->setColor(Qt::red); obsDepthSeries->setMarkerSize(8.0); hindcastSeries = new QLineSeries(); hindcastSeries->setName("hindcast"); - hindcastSeries->setColor(Qt::red); + hindcastSeries->setColor(Qt::green); interpolationSeries = new QLineSeries(); interpolationSeries->setName("interpolation"); From c9b6122473b5d5d4d266a21ad51a2a0c6f8f7c60 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 22 Jul 2024 15:12:13 +0200 Subject: [PATCH 150/179] update watertable --- project/project.cpp | 4 +-- waterTable/waterTable.cpp | 43 ++++++++++++-------------- waterTable/waterTable.h | 22 +++++--------- waterTable/waterTable.pro | 4 +-- waterTable/waterTableChartView.cpp | 48 +++++++++++++++++++----------- waterTable/waterTableChartView.h | 5 ++-- waterTable/waterTableWidget.cpp | 5 ++-- waterTable/waterTableWidget.h | 3 +- waterTable/well.cpp | 5 ---- waterTable/well.h | 7 ++--- 10 files changed, 68 insertions(+), 78 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index b2013d98..7ef9dd2a 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4775,9 +4775,7 @@ void Project::waterTableShowSingleWell(WaterTable &waterTable, const QString &id { DialogSummary* dialogResult = new DialogSummary(waterTable); // show results dialogResult->show(); - WaterTableWidget* chartResult = new WaterTableWidget(idWell, waterTable.getMyDates(), waterTable.getMyHindcastSeries(), - waterTable.getMyInterpolateSeries(), waterTable.getObsDepths(), - quality->getWaterTableMaximumDepth()); + WaterTableWidget* chartResult = new WaterTableWidget(idWell, waterTable, quality->getWaterTableMaximumDepth()); chartResult->show(); return; } diff --git a/waterTable/waterTable.cpp b/waterTable/waterTable.cpp index 12eafbf0..c96e1001 100644 --- a/waterTable/waterTable.cpp +++ b/waterTable/waterTable.cpp @@ -108,8 +108,7 @@ bool WaterTable::computeWTClimate() H_num.push_back(0); } - QMap myDepths = well.getObsDepths(); - QMapIterator it(myDepths); + QMapIterator it(well.depths); while (it.hasNext()) { it.next(); @@ -216,7 +215,6 @@ bool WaterTable::computeETP_allSeries(bool isUpdateAvgCWB) // Ricerca del periodo di correlazione migliore bool WaterTable::computeCWBCorrelation(int stepDays) { - QMap myDepths = well.getObsDepths(); std::vector myCWBSum; std::vector myObsWT; float a = NODATA; @@ -232,7 +230,7 @@ bool WaterTable::computeCWBCorrelation(int stepDays) { myCWBSum.clear(); myObsWT.clear(); - QMapIterator it(myDepths); + QMapIterator it(well.depths); while (it.hasNext()) { @@ -314,8 +312,7 @@ double WaterTable::computeCWB(QDate myDate, int nrDays) // function to compute several statistical indices for watertable depth bool WaterTable::computeWaterTableIndices() { - QMap myDepths = well.getObsDepths(); - QMapIterator it(myDepths); + QMapIterator it(well.depths); std::vector myObs; std::vector myComputed; std::vector myClimate; @@ -491,8 +488,7 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* QDate nextDate; int dT; - QMap myDepths = well.getObsDepths(); - QList keys = myDepths.keys(); + QList keys = well.depths.keys(); // check previuos and next observed data int lastIndex = keys.size() - 1; @@ -501,10 +497,10 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* { indexPrev = i; previousDate = keys[indexPrev]; - previosValue = myDepths[previousDate]; + previosValue = well.depths[previousDate]; indexNext = i; nextDate = keys[indexNext]; - nextValue = myDepths[nextDate]; + nextValue = well.depths[nextDate]; } else { @@ -512,13 +508,13 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* { indexNext = 0; nextDate = keys[indexNext]; - nextValue = myDepths[nextDate]; + nextValue = well.depths[nextDate]; } else if (keys[lastIndex] < myDate) { indexPrev = lastIndex; previousDate = keys[indexPrev]; - previosValue = myDepths[previousDate]; + previosValue = well.depths[previousDate]; } else { @@ -527,10 +523,10 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* { indexPrev = i; previousDate = keys[indexPrev]; - previosValue = myDepths[previousDate]; + previosValue = well.depths[previousDate]; indexNext = i + 1; nextDate = keys[indexNext]; - nextValue = myDepths[nextDate]; + nextValue = well.depths[nextDate]; break; } } @@ -612,30 +608,29 @@ bool WaterTable::getWaterTableInterpolation(QDate myDate, float* myValue, float* void WaterTable::computeWaterTableSeries() { - myDates.clear(); - myHindcastSeries.clear(); - myInterpolateSeries.clear(); + hindcastSeries.clear(); + interpolationSeries.clear(); + float myDelta; int myDeltaDays; - QDate firstObsDate = std::min(well.getFirstDate(), firstMeteoDate); - int numValues = firstObsDate.daysTo(lastMeteoDate) + 1; + firstDate = std::min(well.getFirstDate(), firstMeteoDate); + int numValues = firstDate.daysTo(lastMeteoDate) + 1; for (int i = 0; i < numValues; i++) { - QDate currentDate = firstObsDate.addDays(i); - myDates.push_back(currentDate); + QDate currentDate = firstDate.addDays(i); float currentDepth = getWaterTableDaily(currentDate); - myHindcastSeries.push_back(currentDepth); + hindcastSeries.push_back(currentDepth); if (getWaterTableInterpolation(currentDate, ¤tDepth, &myDelta, &myDeltaDays)) { - myInterpolateSeries.push_back(currentDepth); + interpolationSeries.push_back(currentDepth); } else { - myInterpolateSeries.push_back(NODATA); + interpolationSeries.push_back(NODATA); } } } diff --git a/waterTable/waterTable.h b/waterTable/waterTable.h index b31075ee..f6c9ece7 100644 --- a/waterTable/waterTable.h +++ b/waterTable/waterTable.h @@ -18,6 +18,13 @@ class WaterTable { public: + float WTClimateMonthly[12]; + float WTClimateDaily[366]; + + QDate firstDate; + std::vector hindcastSeries; + std::vector interpolationSeries; + WaterTable(std::vector &inputTMin, std::vector &inputTMax, std::vector &inputPrec, QDate firstMeteoDate, QDate lastMeteoDate, Crit3DMeteoSettings meteoSettings); @@ -59,13 +66,7 @@ class WaterTable QDate getFirstDateWell() { return well.getFirstDate(); } QDate getLastDateWell() { return well.getLastDate(); } - QMap getObsDepths() { return well.getObsDepths(); } - - std::vector getMyDates() { return myDates; } - - std::vector getMyHindcastSeries() { return myHindcastSeries; } - - std::vector getMyInterpolateSeries() { return myInterpolateSeries; } + Well* getWell() { return &well; } void cleanAllMeteoVector(); @@ -92,17 +93,10 @@ class WaterTable float EF; bool isClimateReady; - float WTClimateMonthly[12]; - float WTClimateDaily[366]; int nrObsData; bool isCWBEquationReady; double avgDailyCWB; //[mm] - - // graph - std::vector myDates; - std::vector myHindcastSeries; - std::vector myInterpolateSeries; }; #endif // WATERTABLE_H diff --git a/waterTable/waterTable.pro b/waterTable/waterTable.pro index 55a69b5a..069634f6 100644 --- a/waterTable/waterTable.pro +++ b/waterTable/waterTable.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += widgets charts core xml +QT += core widgets charts QT -= gui TEMPLATE = lib @@ -24,7 +24,7 @@ win32:{ TARGET = waterTable } -INCLUDEPATH += ../crit3dDate ../mathFunctions ../meteo ../interpolation ../gis ../commonChartElements +INCLUDEPATH += ../mathFunctions ../crit3dDate ../meteo ../gis ../commonChartElements SOURCES += \ dialogSelectWell.cpp \ diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index 4fda16c9..97c26da7 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -1,21 +1,26 @@ #include "waterTableChartView.h" + WaterTableChartView::WaterTableChartView(QWidget *parent) : QChartView(new QChart(), parent) { obsDepthSeries = new QScatterSeries(); obsDepthSeries->setName("Observed"); - obsDepthSeries->setColor(Qt::red); + obsDepthSeries->setColor(Qt::green); obsDepthSeries->setMarkerSize(8.0); hindcastSeries = new QLineSeries(); hindcastSeries->setName("hindcast"); - hindcastSeries->setColor(Qt::green); + hindcastSeries->setColor(Qt::red); interpolationSeries = new QLineSeries(); interpolationSeries->setName("interpolation"); interpolationSeries->setColor(QColor(0,0,1)); + climateSeries = new QLineSeries(); + climateSeries->setName("climate"); + climateSeries->setColor(Qt::green); + axisX = new QDateTimeAxis(); axisX->setFormat("yyyy/MM"); axisY = new QValueAxis(); @@ -32,40 +37,46 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : } -void WaterTableChartView::drawWaterTable(std::vector &myDates, std::vector &myHindcastSeries, std::vector &myInterpolateSeries, - QMap obsDepths, float maximumObservedDepth) +void WaterTableChartView::drawWaterTable(WaterTable &waterTable, float maximumObservedDepth) { axisY->setMax(maximumObservedDepth); // unit of observed watertable data, usually [cm] axisY->setMin(0); axisY->setLabelFormat("%d"); axisY->setTickCount(16); - QDateTime firstDate; - firstDate.setDate(myDates[0]); - QDateTime lastDate; - lastDate.setDate(myDates[myDates.size()-1]); + QDateTime firstDateTime, lastDateTime; + int nrDays = int(waterTable.interpolationSeries.size()); + firstDateTime.setDate(waterTable.firstDate); + lastDateTime.setDate(waterTable.firstDate); + lastDateTime = lastDateTime.addDays(nrDays-1); - axisX->setRange(firstDate, lastDate); + axisX->setRange(firstDateTime, lastDateTime); axisX->setTickCount(15); - int nDays = int(myDates.size()); - QDateTime currentDateTime; - for (int day = 0; day < nDays; day++) + QDateTime currentDateTime = firstDateTime; + for (int day = 0; day < nrDays; day++) { - currentDateTime.setDate(myDates[day]); - hindcastSeries->append(currentDateTime.toMSecsSinceEpoch(), myHindcastSeries[day]); - interpolationSeries->append(currentDateTime.toMSecsSinceEpoch(), myInterpolateSeries[day]); + QDate firstJanuary; + firstJanuary.setDate(currentDateTime.date().year(), 1, 1); + int doy = firstJanuary.daysTo(currentDateTime.date()) + 1; + + hindcastSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.hindcastSeries[day]); + interpolationSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.interpolationSeries[day]); + climateSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.WTClimateDaily[doy]); - if(obsDepths.contains(myDates[day])) + if(waterTable.getWell()->depths.contains(currentDateTime.date())) { - int myDepth = obsDepths[myDates[day]]; + int myDepth = waterTable.getWell()->depths[currentDateTime.date()]; obsDepthSeries->append(currentDateTime.toMSecsSinceEpoch(), myDepth); } + + currentDateTime = currentDateTime.addDays(1); } chart()->addSeries(obsDepthSeries); chart()->addSeries(hindcastSeries); chart()->addSeries(interpolationSeries); + chart()->addSeries(climateSeries); obsDepthSeries->attachAxis(axisX); obsDepthSeries->attachAxis(axisY); @@ -73,10 +84,13 @@ void WaterTableChartView::drawWaterTable(std::vector &myDates, std::vecto hindcastSeries->attachAxis(axisY); interpolationSeries->attachAxis(axisX); interpolationSeries->attachAxis(axisY); + climateSeries->attachAxis(axisX); + climateSeries->attachAxis(axisY); connect(obsDepthSeries, &QScatterSeries::hovered, this, &WaterTableChartView::tooltipObsDepthSeries); connect(hindcastSeries, &QLineSeries::hovered, this, &WaterTableChartView::tooltipLineSeries); connect(interpolationSeries, &QLineSeries::hovered, this, &WaterTableChartView::tooltipLineSeries); + foreach(QLegendMarker* marker, chart()->legend()->markers()) { marker->setVisible(true); diff --git a/waterTable/waterTableChartView.h b/waterTable/waterTableChartView.h index 3ca4b30b..278f3b23 100644 --- a/waterTable/waterTableChartView.h +++ b/waterTable/waterTableChartView.h @@ -11,9 +11,7 @@ public: WaterTableChartView(QWidget *parent = 0); - void drawWaterTable(std::vector &myDates, std::vector &myHindcastSeries, - std::vector &myInterpolateSeries, QMap obsDepths, - float maximumObservedDepth); + void drawWaterTable(WaterTable &waterTable, float maximumObservedDepth); void tooltipObsDepthSeries(QPointF point, bool state); void tooltipLineSeries(QPointF point, bool state); @@ -26,6 +24,7 @@ QScatterSeries* obsDepthSeries; QLineSeries* hindcastSeries; QLineSeries* interpolationSeries; + QLineSeries* climateSeries; QValueAxis* axisY; Callout *m_tooltip; diff --git a/waterTable/waterTableWidget.cpp b/waterTable/waterTableWidget.cpp index e5a039f6..de70e5dc 100644 --- a/waterTable/waterTableWidget.cpp +++ b/waterTable/waterTableWidget.cpp @@ -1,8 +1,7 @@ #include "waterTableWidget.h" #include "dialogChangeAxis.h" -WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates, std::vector myHindcastSeries, - std::vector myInterpolateSeries, QMap obsDepths, float maxObservedDepth) +WaterTableWidget::WaterTableWidget(const QString &id, WaterTable &waterTable, float maxObservedDepth) { this->setWindowTitle("Graph Id well: "+ id); this->resize(1240, 700); @@ -33,7 +32,7 @@ WaterTableWidget::WaterTableWidget(const QString &id, std::vector myDates connect(exportInterpolation, &QAction::triggered, this, &WaterTableWidget::on_actionExportInterpolationData); connect(changeXAxis, &QAction::triggered, this, &WaterTableWidget::on_actionChangeXAxis); - waterTableChartView->drawWaterTable(myDates, myHindcastSeries, myInterpolateSeries, obsDepths, maxObservedDepth); + waterTableChartView->drawWaterTable(waterTable, maxObservedDepth); } diff --git a/waterTable/waterTableWidget.h b/waterTable/waterTableWidget.h index 765de3fb..ac8f440d 100644 --- a/waterTable/waterTableWidget.h +++ b/waterTable/waterTableWidget.h @@ -10,8 +10,7 @@ { Q_OBJECT public: - WaterTableWidget(const QString &id, std::vector myDates, std::vector myHindcastSeries, - std::vector myInterpolateSeries, QMap obsDepths, float maxObservedDepth); + WaterTableWidget(const QString &id, WaterTable &waterTable, float maxObservedDepth); ~WaterTableWidget() { ; } diff --git a/waterTable/well.cpp b/waterTable/well.cpp index be4b33c9..963a303b 100644 --- a/waterTable/well.cpp +++ b/waterTable/well.cpp @@ -25,11 +25,6 @@ int Well::getObsDepthNr() } -QMap Well::getObsDepths() -{ - return depths; -} - QDate Well::getFirstDate() { diff --git a/waterTable/well.h b/waterTable/well.h index aeb72800..9d26ca77 100644 --- a/waterTable/well.h +++ b/waterTable/well.h @@ -9,6 +9,8 @@ class Well { public: + QMap depths; + Well(); QString getId() const { return id; } @@ -32,9 +34,6 @@ class Well QDate getLastDate(); int getObsDepthNr(); - - QMap getObsDepths(); - int minValuesPerMonth(); private: @@ -43,8 +42,6 @@ class Well double utmX, utmY; double lat, lon; - QMap depths; - QDate firstDate; QDate lastDate; }; From c533c5495055d25af684ba4e6add480ccf558c10 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 22 Jul 2024 18:06:05 +0200 Subject: [PATCH 151/179] update watertable --- waterTable/waterTableChartView.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index 97c26da7..cc794f11 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -6,8 +6,9 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : { obsDepthSeries = new QScatterSeries(); obsDepthSeries->setName("Observed"); - obsDepthSeries->setColor(Qt::green); - obsDepthSeries->setMarkerSize(8.0); + obsDepthSeries->setColor(QColor(255, 0, 0)); + obsDepthSeries->setBorderColor(QColor(0,0,1)); + obsDepthSeries->setMarkerSize(4.0); hindcastSeries = new QLineSeries(); hindcastSeries->setName("hindcast"); @@ -17,9 +18,12 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : interpolationSeries->setName("interpolation"); interpolationSeries->setColor(QColor(0,0,1)); + QPen pen; + pen.setWidth(2); climateSeries = new QLineSeries(); climateSeries->setName("climate"); - climateSeries->setColor(Qt::green); + climateSeries->setPen(pen); + climateSeries->setColor(QColor(0, 200, 0, 255)); axisX = new QDateTimeAxis(); axisX->setFormat("yyyy/MM"); @@ -58,11 +62,11 @@ void WaterTableChartView::drawWaterTable(WaterTable &waterTable, float maximumOb { QDate firstJanuary; firstJanuary.setDate(currentDateTime.date().year(), 1, 1); - int doy = firstJanuary.daysTo(currentDateTime.date()) + 1; + int doyIndex = firstJanuary.daysTo(currentDateTime.date()); // from 0 to 365 hindcastSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.hindcastSeries[day]); interpolationSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.interpolationSeries[day]); - climateSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.WTClimateDaily[doy]); + climateSeries->append(currentDateTime.toMSecsSinceEpoch(), waterTable.WTClimateDaily[doyIndex]); if(waterTable.getWell()->depths.contains(currentDateTime.date())) { @@ -73,10 +77,11 @@ void WaterTableChartView::drawWaterTable(WaterTable &waterTable, float maximumOb currentDateTime = currentDateTime.addDays(1); } - chart()->addSeries(obsDepthSeries); + chart()->addSeries(hindcastSeries); - chart()->addSeries(interpolationSeries); chart()->addSeries(climateSeries); + chart()->addSeries(interpolationSeries); + chart()->addSeries(obsDepthSeries); obsDepthSeries->attachAxis(axisX); obsDepthSeries->attachAxis(axisY); From dad7fdd0c01f2de03bd31f9cc4ce17db4edeb8db Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 22 Jul 2024 19:38:53 +0200 Subject: [PATCH 152/179] update watertable --- waterTable/waterTableChartView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waterTable/waterTableChartView.cpp b/waterTable/waterTableChartView.cpp index cc794f11..ffd5d83c 100644 --- a/waterTable/waterTableChartView.cpp +++ b/waterTable/waterTableChartView.cpp @@ -6,7 +6,7 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : { obsDepthSeries = new QScatterSeries(); obsDepthSeries->setName("Observed"); - obsDepthSeries->setColor(QColor(255, 0, 0)); + obsDepthSeries->setColor(QColor(0, 192, 255)); obsDepthSeries->setBorderColor(QColor(0,0,1)); obsDepthSeries->setMarkerSize(4.0); From a4ac28a7e9a1a5ea41fe3571580c6720e5580368 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 23 Jul 2024 17:40:39 +0200 Subject: [PATCH 153/179] update 3D --- gis/gis.h | 4 ++-- gis/gisIO.cpp | 40 +++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/gis/gis.h b/gis/gis.h index 375ec0bc..9527dd51 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -254,8 +254,8 @@ bool openRaster(std::string fileName, Crit3DRasterGrid *rasterGrid, int currentUtmZone, std::string &errorStr); - bool readEsriGrid(std::string fileName, Crit3DRasterGrid* rasterGrid, std::string &errorStr); - bool writeEsriGrid(std::string fileName, Crit3DRasterGrid *rasterGrid, std::string &errorStr); + bool readEsriGrid(const std::string &fileName, Crit3DRasterGrid* rasterGrid, std::string &errorStr); + bool writeEsriGrid(const std::string &fileName, Crit3DRasterGrid *rasterGrid, std::string &errorStr); bool readEnviGrid(std::string fileName, Crit3DRasterGrid* rasterGrid, int currentUtmZone, std::string &errorStr); bool writeEnviGrid(std::string fileName, int utmZone, Crit3DRasterGrid *rasterGrid, std::string &errorStr); diff --git a/gis/gisIO.cpp b/gis/gisIO.cpp index c4e82984..62949938 100644 --- a/gis/gisIO.cpp +++ b/gis/gisIO.cpp @@ -112,17 +112,17 @@ namespace gis * \param error string * \return true on success, false otherwise */ - bool readEsriGridHeader(string fileName, gis::Crit3DRasterHeader *header, string &errorStr) + bool readEsriGridHeader(const string &fileName, gis::Crit3DRasterHeader *header, string &errorStr) { string myLine, myKey, upKey, valueStr; int nrKeys = 0; - fileName += ".hdr"; - ifstream myFile (fileName.c_str()); + string myFileName = fileName + ".hdr"; + ifstream myFile (myFileName.c_str()); - if (!myFile.is_open()) + if (! myFile.is_open()) { - errorStr = "Missing file: " + fileName; + errorStr = "Missing file: " + myFileName; return false; } @@ -315,7 +315,7 @@ namespace gis * \param error string * \return true on success, false otherwise */ - bool readRasterFloatData(string fileName, gis::Crit3DRasterGrid *rasterGrid, string &error) + bool readRasterFloatData(const string &fileName, gis::Crit3DRasterGrid *rasterGrid, string &error) { FILE* filePointer; @@ -382,12 +382,12 @@ namespace gis * \param error string pointer * \return true on success, false otherwise */ - bool writeEsriGridHeader(string myFileName, gis::Crit3DRasterHeader *myHeader, string &error) + bool writeEsriGridHeader(const string &fileName, gis::Crit3DRasterHeader *myHeader, string &error) { - myFileName += ".hdr"; + string myFileName = fileName + ".hdr"; ofstream myFile (myFileName.c_str()); - if (!myFile.is_open()) + if (! myFile.is_open()) { error = "File .hdr error."; return false; @@ -429,9 +429,9 @@ namespace gis * \param error string pointer * \return true on success, false otherwise */ - bool writeEsriGridFlt(string myFileName, gis::Crit3DRasterGrid* myGrid, string &error) + bool writeEsriGridFlt(const string &fileName, gis::Crit3DRasterGrid* myGrid, string &error) { - myFileName += ".flt"; + string myFileName = fileName + ".flt"; FILE* filePointer; @@ -454,13 +454,15 @@ namespace gis * \brief Write a ESRI float raster (.hdr and .flt) * \return true on success, false otherwise */ - bool writeEsriGrid(string fileName, Crit3DRasterGrid* rasterGrid, string &error) + bool writeEsriGrid(const string &fileName, Crit3DRasterGrid* rasterGrid, string &errorStr) { - if (gis::writeEsriGridHeader(fileName, rasterGrid->header, error)) - if (gis::writeEsriGridFlt(fileName, rasterGrid, error)) - return true; + if (! gis::writeEsriGridHeader(fileName, rasterGrid->header, errorStr)) + return false; - return false; + if (! gis::writeEsriGridFlt(fileName, rasterGrid, errorStr)) + return false; + + return true; } @@ -468,15 +470,15 @@ namespace gis * \brief Read a ESRI float raster (.hdr and .flt) * \return true on success, false otherwise */ - bool readEsriGrid(string fileName, Crit3DRasterGrid* rasterGrid, string &errorStr) + bool readEsriGrid(const string &fileName, Crit3DRasterGrid* rasterGrid, string &errorStr) { if (rasterGrid == nullptr) return false; rasterGrid->clear(); if(gis::readEsriGridHeader(fileName, rasterGrid->header, errorStr)) { - fileName += ".flt"; - if (gis::readRasterFloatData(fileName, rasterGrid, errorStr)) + string fltFileName = fileName + ".flt"; + if (gis::readRasterFloatData(fltFileName, rasterGrid, errorStr)) { gis::updateMinMaxRasterGrid(rasterGrid); rasterGrid->isLoaded = true; From 1320a20860d3ee9c3e4650c563f95e417bbb4f63 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 23 Jul 2024 19:41:17 +0200 Subject: [PATCH 154/179] update 3D --- project/interpolationCmd.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/project/interpolationCmd.cpp b/project/interpolationCmd.cpp index d7adce14..97620915 100644 --- a/project/interpolationCmd.cpp +++ b/project/interpolationCmd.cpp @@ -264,7 +264,10 @@ bool interpolationRaster(std::vector &myPoints, C return false; } - raster.initializeParameters(*raster.header); + if (mySettings->getUseLocalDetrending()) + { + raster.initializeParameters(*raster.header); + } float myX, myY; std::vector proxyValues; From 99ff9147e134fdce15c24d394296af740507b336 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 23 Jul 2024 20:07:30 +0200 Subject: [PATCH 155/179] update 3D --- graphics/mapGraphicsRasterUtm.cpp | 2 +- meteo/meteo.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/graphics/mapGraphicsRasterUtm.cpp b/graphics/mapGraphicsRasterUtm.cpp index a45a602f..a8937d86 100644 --- a/graphics/mapGraphicsRasterUtm.cpp +++ b/graphics/mapGraphicsRasterUtm.cpp @@ -370,7 +370,7 @@ bool RasterUtmObject::drawRaster(QPainter* painter) // check outliers (transparent) if (_rasterPointer->colorScale->isHideOutliers()) { - if (value <= _rasterPointer->colorScale->minimum() || value >= _rasterPointer->colorScale->maximum()) + if (value <= _rasterPointer->colorScale->minimum() || value > _rasterPointer->colorScale->maximum()) continue; } diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index 21709b86..c1ff9820 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -789,6 +789,8 @@ bool setColorScale(meteoVariable variable, Crit3DColorScale *colorScale) if (variable == snowFall || variable == snowWaterEquivalent || variable == snowLiquidWaterContent || variable == snowMelt) { + colorScale->setMinimum(0); + colorScale->setFixedRange(true); colorScale->setHideOutliers(true); colorScale->setTransparent(true); } From 7ef386e365acd398ca048cb40c041fb0f5f1a1de Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 23 Jul 2024 20:13:10 +0200 Subject: [PATCH 156/179] update 3D --- meteo/meteo.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index c1ff9820..21709b86 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -789,8 +789,6 @@ bool setColorScale(meteoVariable variable, Crit3DColorScale *colorScale) if (variable == snowFall || variable == snowWaterEquivalent || variable == snowLiquidWaterContent || variable == snowMelt) { - colorScale->setMinimum(0); - colorScale->setFixedRange(true); colorScale->setHideOutliers(true); colorScale->setTransparent(true); } From f5efec093e62640ef963c9122bb5392c6b1be377 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 24 Jul 2024 15:55:00 +0200 Subject: [PATCH 157/179] update 3D --- project/project.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 7ef9dd2a..dc86f274 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -1102,7 +1102,8 @@ bool Project::loadDEM(QString myFileName) setProxyDEM(); interpolationSettings.setProxyLoaded(false); - if (! updateProxy()) return false; + if (! updateProxy()) + return false; //set interpolation settings DEM interpolationSettings.setCurrentDEM(&DEM); @@ -1899,7 +1900,7 @@ bool Project::loadProxyGrids() } else { - errorString = "Error loading proxy grid " + fileName; + errorString = "Error loading raster proxy:\n" + fileName + "\nHow to fix it: check the proxy section in the parameters.ini"; return false; } @@ -1972,13 +1973,11 @@ bool Project::updateProxy() { if (! interpolationSettings.getProxyLoaded()) { - if (loadProxyGrids()) - { - interpolationSettings.setProxyLoaded(true); - } - else + if (! loadProxyGrids()) return false; + interpolationSettings.setProxyLoaded(true); + if (meteoPointsDbHandler != nullptr) { if (! readProxyValues()) From d46e60f61790f311e84555c78a1e7790ada4ef77 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 26 Jul 2024 19:35:59 +0200 Subject: [PATCH 158/179] update vine3D --- crop/landUnit.cpp | 10 ---- crop/landUnit.h | 2 - grapevine/grapevine.cpp | 115 +++++++++++++++++++++------------------- grapevine/grapevine.h | 29 +++++----- project/project.cpp | 9 +++- 5 files changed, 82 insertions(+), 83 deletions(-) diff --git a/crop/landUnit.cpp b/crop/landUnit.cpp index be279418..d39f754d 100644 --- a/crop/landUnit.cpp +++ b/crop/landUnit.cpp @@ -59,13 +59,3 @@ bool loadLandUnitList(const QSqlDatabase &dbCrop, std::vector &l return true; } - - -int getLandUnitIndex(const std::vector &landUnitList, int idLandUnit) -{ - for (int index = 0; index < int(landUnitList.size()); index++) - if (landUnitList[index].id == idLandUnit) - return index; - - return NODATA; -} diff --git a/crop/landUnit.h b/crop/landUnit.h index be563b3d..fb11f46c 100644 --- a/crop/landUnit.h +++ b/crop/landUnit.h @@ -23,7 +23,5 @@ bool loadLandUnitList(const QSqlDatabase &dbCrop, std::vector &landUnitList, QString &errorStr); - int getLandUnitIndex(const std::vector &landUnitList, int idLandUnit); - #endif // LANDUNIT_H diff --git a/grapevine/grapevine.cpp b/grapevine/grapevine.cpp index 22125020..83e04c5d 100644 --- a/grapevine/grapevine.cpp +++ b/grapevine/grapevine.cpp @@ -21,9 +21,7 @@ const float LAIMIN = 0.01f; Vine3D_Grapevine::Vine3D_Grapevine() -{ -} - +{} bool Vine3D_Grapevine::compute(bool computeDaily, int secondsPerStep, Crit3DModelCase* modelCase, double chlorophyll) { @@ -106,9 +104,9 @@ bool Vine3D_Grapevine::compute(bool computeDaily, int secondsPerStep, Crit3DMode grassTranspiration(modelCase); return(true); - } + void Vine3D_Grapevine::resetLayers() { for (int i=0 ; i < nrMaxLayers ; i++) @@ -121,6 +119,7 @@ void Vine3D_Grapevine::resetLayers() } } + void Vine3D_Grapevine::initializeLayers(int myMaxLayers) { nrMaxLayers = myMaxLayers; @@ -156,22 +155,25 @@ bool Vine3D_Grapevine::setWeather(double meanDailyTemp, double temp, double irra myMeanDailyTemperature = meanDailyTemp; double deltaRelHum = MAXVALUE(100.0 - myRelativeHumidity, 0.01); myVaporPressureDeficit = 0.01 * deltaRelHum * 613.75 * exp(17.502 * myInstantTemp / (240.97 + myInstantTemp)); - //globalRadiation = globRad; - if ((int(prec) != NODATA) && (int(temp) != NODATA) && (int(windSpeed) != NODATA) && (int(irradiance) != NODATA) && (int(relativeHumidity) != NODATA) && (int(atmosphericPressure) != NODATA)) isReadingOK = true ; - return isReadingOK ; + + if ((int(prec) != NODATA) && (int(temp) != NODATA) && (int(windSpeed) != NODATA) + && (int(irradiance) != NODATA) && (int(relativeHumidity) != NODATA) && (int(atmosphericPressure) != NODATA)) + isReadingOK = true; + + return isReadingOK; } + bool Vine3D_Grapevine::setDerivedVariables(double diffuseIrradiance, double directIrradiance, double cloudIndex, double sunElevation) { bool isReadingOK = false; myDiffuseIrradiance = diffuseIrradiance ; myDirectIrradiance = directIrradiance ; - //myLongWaveIrradiance = longWaveIrradiance ; myCloudiness = MINVALUE(1,MAXVALUE(0,cloudIndex)) ; - //myAirVapourPressure = airVapourPressure ; mySunElevation = sunElevation; - if (int(sunElevation) != NODATA && int(diffuseIrradiance) != NODATA && int(directIrradiance) != NODATA - && int(cloudIndex) != NODATA) isReadingOK = true ; + if (int(sunElevation) != NODATA && int(diffuseIrradiance) != NODATA && int(directIrradiance) != NODATA && int(cloudIndex) != NODATA) + isReadingOK = true ; + return isReadingOK ; } @@ -185,32 +187,45 @@ void Vine3D_Grapevine::initializeWaterStress(Crit3DModelCase* modelCase) } -bool Vine3D_Grapevine::setSoilProfile(Crit3DModelCase* modelCase, double* myWiltingPoint, double* myFieldCapacity, - double* myPsiSoilProfile, double* mySoilWaterContentProfile, - double* mySoilWaterContentFC, double* mySoilWaterContentWP) +bool Vine3D_Grapevine::setSoilProfile(Crit3DModelCase* modelCase, std::vector& myWiltingPoint, std::vector& myFieldCapacity, + std::vector& myPsiSoilProfile, std::vector& mySoilWaterContentProfile, + std::vector& mySoilWaterContentFC, std::vector& mySoilWaterContentWP) { - double psiSoilProfile; - double logPsiSoilAverage = 0.; - double logPsiFCAverage = 0.; - double soilFieldCapacity; + // check last Soil layer + int lastLayer = modelCase->soilLayersNr - 1; + for (int i = 1; i < modelCase->soilLayersNr; i++) + { + if (isEqual(myPsiSoilProfile[i], NODATA) || isEqual(myFieldCapacity[i], NODATA) || isEqual(mySoilWaterContentProfile[i], NODATA) + || isEqual(mySoilWaterContentProfile[i], NODATA) || isEqual(mySoilWaterContentWP[i], NODATA)) + { + lastLayer = i-1; + break; + } + } + if (lastLayer == 0) + return false; psiSoilAverage = 0.; psiFieldCapacityAverage = 0.; - if (int(myWiltingPoint[int(modelCase->soilLayersNr / 2)]) == NODATA) - return false; + // initialize vector + for (int i = 1; i < modelCase->soilLayersNr; i++) + { + transpirationLayer[i] = 0.; + transpirationCumulatedGrass[i] = 0.; + fractionTranspirableSoilWaterProfile[i] = 0.; + } - wiltingPoint = myWiltingPoint[int(modelCase->soilLayersNr / 2)] / 101.97; // conversion from mH2O to MPa + int midLayer = (lastLayer + 1) / 2; + wiltingPoint = myWiltingPoint[midLayer] / 101.97; // conversion from mH2O to MPa //layer 0: surface, no soil - for (int i = 1; i < modelCase->soilLayersNr; i++) + double logPsiSoilAverage = 0.; + double logPsiFCAverage = 0.; + for (int i = 1; i <= lastLayer; i++) { - if (isEqual(myPsiSoilProfile[i], NODATA) || isEqual(myFieldCapacity[i], NODATA) || isEqual(mySoilWaterContentProfile[i], NODATA) - || isEqual(mySoilWaterContentProfile[i], NODATA) || isEqual(mySoilWaterContentWP[i], NODATA)) - return false; - - soilFieldCapacity = myFieldCapacity[i]/101.97; // conversion from mH2O to MPa - psiSoilProfile = MINVALUE(myPsiSoilProfile[i],-1.)/101.97 ; // conversion from mH2O to MPa + double soilFieldCapacity = myFieldCapacity[i] / 101.97; // conversion from mH2O to MPa + double psiSoilProfile = MINVALUE(myPsiSoilProfile[i], -1.) / 101.97 ; // conversion from mH2O to MPa logPsiSoilAverage += log(-psiSoilProfile) * modelCase->rootDensity[i]; logPsiFCAverage += log(-soilFieldCapacity) * modelCase->rootDensity[i]; } @@ -219,28 +234,26 @@ bool Vine3D_Grapevine::setSoilProfile(Crit3DModelCase* modelCase, double* myWilt psiFieldCapacityAverage = -exp(logPsiFCAverage); fractionTranspirableSoilWaterAverage = 0; - double waterContent, waterContentFC, waterContentWP; - - for (int i = 0; i < modelCase->soilLayersNr; i++) + for (int i = 0; i <= lastLayer; i++) { - waterContent = mySoilWaterContentProfile[i]; - waterContentFC = mySoilWaterContentFC[i]; - waterContentWP = mySoilWaterContentWP[i]; + double waterContent = mySoilWaterContentProfile[i]; + double waterContentFC = mySoilWaterContentFC[i]; + double waterContentWP = mySoilWaterContentWP[i]; fractionTranspirableSoilWaterProfile[i] = MAXVALUE(0, MINVALUE(1, (waterContent - waterContentWP) / (waterContentFC - waterContentWP))); fractionTranspirableSoilWaterAverage += fractionTranspirableSoilWaterProfile[i] * modelCase->rootDensity[i]; - transpirationLayer[i] = 0.; - transpirationCumulatedGrass[i] = 0. ; } + return true ; } -bool Vine3D_Grapevine::setStatePlant(TstatePlant myStatePlant, bool isVineyard) + +bool Vine3D_Grapevine::setStatePlant(TstatePlant myStatePlant, bool isVineyard_) { statePlant = myStatePlant; this->statePlant.outputPlant.transpirationNoStress = 0.; - if (! isVineyard) + if (! isVineyard_) { statePlant.outputPlant.brixBerry = NODATA; statePlant.statePheno.stage = NODATA; @@ -248,17 +261,8 @@ bool Vine3D_Grapevine::setStatePlant(TstatePlant myStatePlant, bool isVineyard) statePlant.stateGrowth.leafAreaIndex = NODATA; statePlant.stateGrowth.fruitBiomass = NODATA; } - return true; -} - -TstatePlant Vine3D_Grapevine::getStatePlant() -{ - return(this->statePlant); -} -ToutputPlant Vine3D_Grapevine::getOutputPlant() -{ - return (this->statePlant.outputPlant); + return true; } @@ -268,13 +272,13 @@ void Vine3D_Grapevine::getFixSimulationParameters() parameterBindiMigliettaFix.a = -0.28; parameterBindiMigliettaFix.b = 0.04; parameterBindiMigliettaFix.c = -0.015; - //parameterBindiMigliettaFix.baseTemperature = 10; - //parameterBindiMigliettaFix.tempMaxThreshold = 35; parameterBindiMigliettaFix.extinctionCoefficient = 0.5; parameterBindiMigliettaFix.shadedSurface = 0.8; + // Wang Leuning parameters parameterWangLeuningFix.stomatalConductanceMin = 0.008; parameterWangLeuningFix.optimalTemperatureForPhotosynthesis = 298.15; + // fenovitis parameters parameterPhenoVitisFix.a= 0.005; parameterPhenoVitisFix.optimalChillingTemp = 2.8; @@ -525,6 +529,8 @@ void Vine3D_Grapevine::radiationAbsorption() { sunlit.leafAreaIndex = 0.0 ; sunlit.absorbedPAR = 0.0 ; + + // TODO: non servono? sunlitAbsorbedNIR = 0.0 ; sunlitAbsorbedLW = 0.0 ; sunlit.isothermalNetRadiation = 0.0 ; @@ -537,12 +543,13 @@ void Vine3D_Grapevine::radiationAbsorption() shadedAbsorbedLW= dum[16] * (UPSCALINGFUNC(diffuseLightK,statePlant.stateGrowth.leafAreaIndex) - UPSCALINGFUNC(directLightK+diffuseLightK,statePlant.stateGrowth.leafAreaIndex)) ; shaded.isothermalNetRadiation = shaded.absorbedPAR + shadedAbsorbedNIR + shadedAbsorbedLW ; } + // Convert absorbed PAR into units of mol m-2 s-1 sunlit.absorbedPAR *= 4.57E-6 ; shaded.absorbedPAR *= 4.57E-6 ; - } + void Vine3D_Grapevine::leafTemperature() { // taken from Hydrall Model, Magnani UNIBO @@ -695,7 +702,8 @@ void Vine3D_Grapevine::aerodynamicalCoupling() { sunlitDeltaTemp = 0.0; } - sunlitDeltaTemp = 0.0; + sunlitDeltaTemp = 0.0; // TODO: check + sunlit.leafTemperature = myInstantTemp + sunlitDeltaTemp + ZEROCELSIUS ; //sunlit big-leaf stomatalConductanceWater = 10.0/shaded.leafAreaIndex ; //dummy stom res for shaded big-leaf //if (shaded.isothermalNetRadiation > 100) stomatalConductanceWater *= pow(100/shaded.isothermalNetRadiation,0.5); @@ -802,10 +810,9 @@ void Vine3D_Grapevine::upscale(TVineCultivar *cultivar) sunlit.darkRespiration = 0.0; sunlit.maximalCarboxylationRate = 0.0; } - - } + void Vine3D_Grapevine::photosynthesisKernel(TVineCultivar* cultivar, double COMP,double GAC,double GHR,double GSCD,double J,double KC,double KO ,double RD,double RNI,double STOMWL,double VCmax,double *ASS,double *GSC,double *TR) { diff --git a/grapevine/grapevine.h b/grapevine/grapevine.h index a0d18faa..1ff7442c 100644 --- a/grapevine/grapevine.h +++ b/grapevine/grapevine.h @@ -41,9 +41,9 @@ enum phenoStage {endoDormancy, ecoDormancy , budBurst , flowering , fruitSet, veraison, physiologicalMaturity, vineSenescence}; enum TfieldOperation {irrigationOperation, grassSowing, grassRemoving, trimming, leafRemoval, clusterThinning, harvesting, tartaricAnalysis}; - enum Crit3DLanduse {landuse_nodata, landuse_bare, landuse_vineyard}; + enum GrapevineLanduse {landuse_nodata, landuse_bare, landuse_vineyard}; - const std::map landuseNames = { + const std::map landuseNames = { { "UNDEFINED", landuse_nodata }, { "BARESOIL", landuse_bare }, { "VINEYARD", landuse_vineyard} @@ -191,7 +191,7 @@ struct Crit3DModelCase { int id; - Crit3DLanduse landuse; + GrapevineLanduse landuse; int soilIndex; float shootsPerPlant; @@ -300,8 +300,7 @@ double psiSoilAverage; double psiFieldCapacityAverage; - //double* layerRootDensity; - double totalStomatalConductance, totalStomatalConductanceNoStress ; + double totalStomatalConductance, totalStomatalConductanceNoStress; double transpirationInstant; double* currentProfile; double* transpirationInstantLayer; //molH2O m^-2 s^-1 @@ -327,8 +326,6 @@ bool isAmphystomatic ; double specificLeafArea ; double alphaLeuning ; - //double leafNitrogen ; - //double entropicFactorCarboxyliation,entropicFactorElectronTransporRate ; Vine3D_SunShade shaded ; Vine3D_SunShade sunlit ; @@ -374,7 +371,7 @@ double getWaterStressByPsiSoil(double myPsiSoil,double psiSoilStressParameter,double exponentialFactorForPsiRatio); double getWaterStressSawFunction(int index, TVineCultivar *cultivar); - //bool getExtractedWaterFromGrassTranspirationandEvaporation(double* myWaterExtractionProfile); + double getWaterStressSawFunctionAverage(TVineCultivar* cultivar); double getGrassTranspiration(double stress, double laiGrassMax, double sensitivityToVPD, double fieldCoverByPlant); double getFallowTranspiration(double stress, double laiGrassMax, double sensitivityToVPD); @@ -392,6 +389,11 @@ public: Vine3D_Grapevine(); + TstatePlant getStatePlant(){ return statePlant; } + ToutputPlant getOutputPlant() { return statePlant.outputPlant; } + + bool setStatePlant(TstatePlant myStatePlant, bool isVineyard_); + //void initializeGrapevineModel(TVineCultivar* cultivar, double secondsPerStep); void initializeLayers(int myMaxLayers); bool initializeStatePlant(int doy, Crit3DModelCase *vineField); @@ -409,15 +411,12 @@ double prec , double relativeHumidity , double windSpeed, double atmosphericPressure); bool setDerivedVariables (double diffuseIrradiance, double directIrradiance, double cloudIndex, double sunElevation); - bool setSoilProfile(Crit3DModelCase *modelCase, double* myWiltingPoint, double *myFieldCapacity, - double *myPsiSoilProfile , double *mySoilWaterContentProfile, - double* mySoilWaterContentFC, double* mySoilWaterContentWP); - bool setStatePlant(TstatePlant myStatePlant, bool isVineyard); - TstatePlant getStatePlant(); - ToutputPlant getOutputPlant(); + bool setSoilProfile(Crit3DModelCase* modelCase, std::vector& myWiltingPoint, std::vector& myFieldCapacity, + std::vector& myPsiSoilProfile, std::vector& mySoilWaterContentProfile, + std::vector& mySoilWaterContentFC, std::vector& mySoilWaterContentWP); + double* getExtractedWater(Crit3DModelCase* modelCase); - //bool getOutputPlant(int hour, ToutputPlant *outputPlant); double getStressCoefficient(); double getRealTranspirationGrapevine(Crit3DModelCase *modelCase); double getRealTranspirationGrass(Crit3DModelCase *modelCase); diff --git a/project/project.cpp b/project/project.cpp index dc86f274..73410dd6 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -934,8 +934,13 @@ Crit3DTime Project::getCrit3DCurrentTime() QDateTime Project::getCurrentTime() { QDateTime myDateTime; - myDateTime.setDate(this->currentDate); - return myDateTime.addSecs(this->currentHour * HOUR_SECONDS); + if (gisSettings.isUTC) + { + myDateTime.setTimeSpec(Qt::UTC); + } + + myDateTime.setDate(currentDate); + return myDateTime.addSecs(currentHour * HOUR_SECONDS); } From 361544f3ecc1830e2a9f41cbb7faba4305431fce Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 29 Jul 2024 20:34:05 +0200 Subject: [PATCH 159/179] update 3D --- soilFluxes3D/header/soilFluxes3D.h | 1 + soilFluxes3D/soilFluxes3D.cpp | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/soilFluxes3D/header/soilFluxes3D.h b/soilFluxes3D/header/soilFluxes3D.h index 7341310c..28d51d5a 100644 --- a/soilFluxes3D/header/soilFluxes3D.h +++ b/soilFluxes3D/header/soilFluxes3D.h @@ -51,6 +51,7 @@ // WATER __EXTERN int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, int conductivityMeanType, float horizVertRatioConductivity); __EXTERN int DLL_EXPORT __STDCALL setWaterContent(long index, double myWaterContent); + __EXTERN int DLL_EXPORT __STDCALL setDegreeOfSaturation(long nodeIndex, double degreeOfSaturation); __EXTERN int DLL_EXPORT __STDCALL setMatricPotential(long index, double psi); __EXTERN int DLL_EXPORT __STDCALL setTotalPotential(long index, double totalPotential); __EXTERN int DLL_EXPORT __STDCALL setPrescribedTotalPotential(long index, double prescribedTotalPotential); diff --git a/soilFluxes3D/soilFluxes3D.cpp b/soilFluxes3D/soilFluxes3D.cpp index 33d9fc19..af54b808 100644 --- a/soilFluxes3D/soilFluxes3D.cpp +++ b/soilFluxes3D/soilFluxes3D.cpp @@ -499,7 +499,7 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief setWaterContent * \param nodeIndex - * \param waterContent [m^3 m^-3] + * \param waterContent [m] surface - [m3 m-3] sub-surface * \return OK/ERROR */ int DLL_EXPORT __STDCALL setWaterContent(long nodeIndex, double waterContent) @@ -531,6 +531,31 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, } + /*! + * \brief setDegreeOfSaturation + * \param nodeIndex + * \param degreeOfSaturation [-] (only sub-surface) + * \return OK/ERROR + */ + int DLL_EXPORT __STDCALL setDegreeOfSaturation(long nodeIndex, double degreeOfSaturation) + { + if (nodeListPtr == nullptr) return MEMORY_ERROR; + + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) return INDEX_ERROR; + + if (nodeListPtr[nodeIndex].isSurface) return INDEX_ERROR; + + if ((degreeOfSaturation < 0.) || (degreeOfSaturation > 1.)) return PARAMETER_ERROR; + + nodeListPtr[nodeIndex].Se = degreeOfSaturation; + nodeListPtr[nodeIndex].H = nodeListPtr[nodeIndex].z - psi_from_Se(nodeIndex); + nodeListPtr[nodeIndex].oldH = nodeListPtr[nodeIndex].H; + nodeListPtr[nodeIndex].k = computeK(nodeIndex); + + return CRIT3D_OK; + } + + /*! * \brief setWaterSinkSource * \param nodeIndex From 8a05e787fd2c27909ec5ebcdcf72e3d1e71fa004 Mon Sep 17 00:00:00 2001 From: giadasan Date: Tue, 30 Jul 2024 14:10:11 +0200 Subject: [PATCH 160/179] update output db writing --- outputPoints/dbOutputPointsHandler.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/outputPoints/dbOutputPointsHandler.cpp b/outputPoints/dbOutputPointsHandler.cpp index 3e17f7b1..acd7db28 100644 --- a/outputPoints/dbOutputPointsHandler.cpp +++ b/outputPoints/dbOutputPointsHandler.cpp @@ -97,23 +97,26 @@ bool Crit3DOutputPointsDbHandler::addCriteria3DColumn(const QString &tableName, } // column name + if (depth != NODATA) + { QString newField = variableString + "_" + QString::number(depth); + } // column exists already QList fieldList = getFields(&_db, tableName); - if ( fieldList.contains(newField) ) + if ( fieldList.contains(variableString) ) { return true; } // add column QString queryString = "ALTER TABLE '" + tableName + "'"; - queryString += " ADD " + newField + " REAL"; + queryString += " ADD " + variableString + " REAL"; QSqlQuery myQuery = _db.exec(queryString); if (myQuery.lastError().isValid()) { - errorStr = "Error in add column: " + newField + "\n" + myQuery.lastError().text(); + errorStr = "Error in add column: " + variableString + "\n" + myQuery.lastError().text(); return false; } @@ -193,7 +196,7 @@ bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &table } int nrValues = int(varList.size()) * nrSoilLayers; - if (nrValues != values.size()) + if (nrValues != int(values.size())) { errorStr = "Error saving values: number of values is not as expected."; return false; From 3711cec56f35e806c5f964f976e831038a5abd9c Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 30 Jul 2024 14:12:46 +0200 Subject: [PATCH 161/179] update 3D --- soilFluxes3D/header/soilFluxes3D.h | 2 +- soilFluxes3D/header/solver.h | 2 +- soilFluxes3D/soilFluxes3D.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/soilFluxes3D/header/soilFluxes3D.h b/soilFluxes3D/header/soilFluxes3D.h index 28d51d5a..9c8ebd07 100644 --- a/soilFluxes3D/header/soilFluxes3D.h +++ b/soilFluxes3D/header/soilFluxes3D.h @@ -49,7 +49,7 @@ __EXTERN int DLL_EXPORT __STDCALL setNodeSurface(long nodeIndex, int surfaceIndex); // WATER - __EXTERN int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, int conductivityMeanType, float horizVertRatioConductivity); + __EXTERN int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, int conductivityMeanType, float conductivityHorizVertRatio); __EXTERN int DLL_EXPORT __STDCALL setWaterContent(long index, double myWaterContent); __EXTERN int DLL_EXPORT __STDCALL setDegreeOfSaturation(long nodeIndex, double degreeOfSaturation); __EXTERN int DLL_EXPORT __STDCALL setMatricPotential(long index, double psi); diff --git a/soilFluxes3D/header/solver.h b/soilFluxes3D/header/solver.h index ba8739c2..52195724 100644 --- a/soilFluxes3D/header/solver.h +++ b/soilFluxes3D/header/solver.h @@ -1,7 +1,7 @@ #ifndef SOLVER_H #define SOLVER_H - inline double square(double x) {return ((x)*(x));} + inline double square(double x) { return ((x)*(x)); } double distance(unsigned long index1, unsigned long index2); diff --git a/soilFluxes3D/soilFluxes3D.cpp b/soilFluxes3D/soilFluxes3D.cpp index af54b808..4cb717a9 100644 --- a/soilFluxes3D/soilFluxes3D.cpp +++ b/soilFluxes3D/soilFluxes3D.cpp @@ -182,18 +182,18 @@ int DLL_EXPORT __STDCALL setNumericalParameters(float minDeltaT, float maxDeltaT * k_lateral_vertical_ratio = 10 * \param waterRetentionCurve * \param conductivityMeanType - * \param horizVertRatioConductivity + * \param conductivityHorizVertRatio * \return OK or PARAMETER_ERROR */ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, - int conductivityMeanType, float horizVertRatioConductivity) + int conductivityMeanType, float conductivityHorizVertRatio) { myParameters.waterRetentionCurve = waterRetentionCurve; myParameters.meanType = conductivityMeanType; - if ((horizVertRatioConductivity >= 0.1) && (horizVertRatioConductivity <= 100)) + if ((conductivityHorizVertRatio >= 0.1) && (conductivityHorizVertRatio <= 100)) { - myParameters.k_lateral_vertical_ratio = horizVertRatioConductivity; + myParameters.k_lateral_vertical_ratio = conductivityHorizVertRatio; return CRIT3D_OK; } else From 362514e0b57b32c6eb6e9ee4a862ae458a4daa08 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 30 Jul 2024 16:42:09 +0200 Subject: [PATCH 162/179] set criteria output depth --- outputPoints/dbOutputPointsHandler.cpp | 79 +++++++++++++------------- outputPoints/dbOutputPointsHandler.h | 16 ++++-- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/outputPoints/dbOutputPointsHandler.cpp b/outputPoints/dbOutputPointsHandler.cpp index acd7db28..ce6b0ab0 100644 --- a/outputPoints/dbOutputPointsHandler.cpp +++ b/outputPoints/dbOutputPointsHandler.cpp @@ -99,7 +99,7 @@ bool Crit3DOutputPointsDbHandler::addCriteria3DColumn(const QString &tableName, // column name if (depth != NODATA) { - QString newField = variableString + "_" + QString::number(depth); + variableString += "_" + QString::number(depth); } // column exists already @@ -181,21 +181,18 @@ bool Crit3DOutputPointsDbHandler::saveHourlyMeteoData(const QString &tableName, } -// layerDepth [m] +// variableDepth [cm] bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &tableName, const QDateTime& myTime, - const std::vector& varList, - const std::vector& values, - const std::vector & layerDepth, - QString &errorStr) + const std::vector& values, + const std::vector& waterContentDepth, + const std::vector& waterPotentialDepth, + const std::vector& degreeOfSaturationDepth, + const std::vector& factorOfSafetyDepth, + QString &errorStr) { - int nrSoilLayers = int(layerDepth.size()) - 1; - if (nrSoilLayers <= 0) - { - errorStr = "Error saving values: missing soil layers."; - return false; - } + int nrValues = waterContentDepth.size() + waterPotentialDepth.size() + + degreeOfSaturationDepth.size() + factorOfSafetyDepth.size(); - int nrValues = int(varList.size()) * nrSoilLayers; if (nrValues != int(values.size())) { errorStr = "Error saving values: number of values is not as expected."; @@ -204,35 +201,16 @@ bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &table QString timeStr = myTime.toString("yyyy-MM-dd HH:mm:ss"); - // field list - QString setList = ""; - for (unsigned int i = 0; i < varList.size(); i++) - { - QString variableString = QString::fromStdString(getCriteria3DVarName(varList[i])); - if (variableString == "") - { - errorStr = "Missing variable name."; - return false; - } - - for (int layer = 1; layer <= nrSoilLayers; layer++) - { - int depth = round(layerDepth[layer] * 100); // [cm] + QList valueList; + int firstIndex = 0; + appendCriteria3DOutputValue(volumetricWaterContent, waterContentDepth, values, firstIndex, valueList); + appendCriteria3DOutputValue(waterMatricPotential, waterPotentialDepth, values, firstIndex, valueList); + appendCriteria3DOutputValue(degreeOfSaturation, degreeOfSaturationDepth, values, firstIndex, valueList); + appendCriteria3DOutputValue(factorOfSafety, factorOfSafetyDepth, values, firstIndex, valueList); - QString fieldName = variableString + "_" + QString::number(depth); - setList += "'" + fieldName + "'="; - - int index = i * nrSoilLayers + layer - 1; - QString valueStr = QString::number(values[index], 'f', 3); - setList += valueStr; - - if (index < (nrValues - 1)) - setList += ","; - } - } QSqlQuery qry(_db); - QString queryString = QString("UPDATE '%1' SET %2 WHERE DATE_TIME ='%3'").arg(tableName, setList, timeStr); + QString queryString = QString("UPDATE '%1' SET %2 WHERE DATE_TIME ='%3'").arg(tableName, valueList.join(','), timeStr); if (! qry.exec(queryString)) { errorStr = QString("Error in query: " + queryString + "\n" + qry.lastError().text()); @@ -242,3 +220,26 @@ bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &table return true; } + +void Crit3DOutputPointsDbHandler::appendCriteria3DOutputValue(criteria3DVariable myVar, const std::vector &depthList, + const std::vector& values, int &firstIndex, + QList &outputList) +{ + QString variableString = QString::fromStdString(getCriteria3DVarName(myVar)); + + for (int l = 0; l < depthList.size(); l++) + { + float depth_cm = depthList[l]; + QString fieldName = variableString + "_" + QString::number(depth_cm); + + int index = firstIndex + l; + QString valueStr = QString::number(values[index], 'f', 3); + + QString assignStr = "'" + fieldName + "'=" + valueStr; + + outputList.push_back(assignStr); + } + + firstIndex += depthList.size(); +} + diff --git a/outputPoints/dbOutputPointsHandler.h b/outputPoints/dbOutputPointsHandler.h index 00742d1f..b53bf3ce 100644 --- a/outputPoints/dbOutputPointsHandler.h +++ b/outputPoints/dbOutputPointsHandler.h @@ -33,12 +33,20 @@ const std::vector &varList, const std::vector &values, QString &errorStr); - bool saveHourlyCriteria3D_Data(const QString &tableName, const QDateTime &myTime, - const std::vector &varList, - const std::vector &values, - const std::vector &layerDepth, QString &errorStr); + bool saveHourlyCriteria3D_Data(const QString &tableName, const QDateTime& myTime, + const std::vector& values, + const std::vector& waterContentDepth, + const std::vector& waterPotentialDepth, + const std::vector& degreeOfSaturationDepth, + const std::vector& factorOfSafetyDepth, + QString &errorStr); + + void appendCriteria3DOutputValue(criteria3DVariable myVar, const std::vector &depthList, + const std::vector& values, int &firstIndex, + QList &outputList); private: + QSqlDatabase _db; QString errorString; }; From 093463ad70e311ffaae054a3bbd2175384e5aa05 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 30 Jul 2024 19:02:56 +0200 Subject: [PATCH 163/179] clean vine3d --- project/project.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/project/project.cpp b/project/project.cpp index 73410dd6..b16288ef 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2804,7 +2804,9 @@ float Project::meteoDataConsistency(meteoVariable myVar, const Crit3DTime& timeI { float dataConsistency = 0.0; for (int i = 0; i < nrMeteoPoints; i++) + { dataConsistency = MAXVALUE(dataConsistency, meteoPoints[i].obsDataConsistencyH(myVar, timeIni, timeFin)); + } return dataConsistency; } From 0011e8eae95493b3c157b3b408ee8f30fe9fc9ea Mon Sep 17 00:00:00 2001 From: Gabriele Antolini Date: Wed, 31 Jul 2024 16:13:42 +0200 Subject: [PATCH 164/179] error parameters --- project/project.cpp | 24 ++---------------------- project/project.h | 2 +- proxyWidget/localProxyWidget.cpp | 25 ------------------------- proxyWidget/proxyWidget.cpp | 24 ------------------------ 4 files changed, 3 insertions(+), 72 deletions(-) diff --git a/project/project.cpp b/project/project.cpp index 73410dd6..a2240190 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -198,7 +198,7 @@ void Project::setProxyDEM() } -bool Project::checkProxy(const Crit3DProxy &myProxy, QString* error) +bool Project::checkProxy(Crit3DProxy &myProxy, QString* error) { std::string name_ = myProxy.getName(); @@ -688,25 +688,6 @@ bool Project::loadParameters(QString parametersFileName) if (parameters->contains("stddev_threshold")) myProxy->setStdDevThreshold(parameters->value("stddev_threshold").toFloat()); - /*if (parameters->contains("fitting_parameters")) - { - unsigned int nrParameters; - - if (getProxyPragaName(name_.toStdString()) == proxyHeight) - nrParameters = 5; - else - nrParameters = 2; - - myList = parameters->value("fitting_parameters").toStringList(); - if (myList.size() != nrParameters*2 && myList.size() != (nrParameters-1)*2 && myList.size() != (nrParameters+1)*2) //TODO: change - { - errorString = "Wrong number of fitting parameters for proxy: " + name_; - return false; - } - - myProxy->setFittingParametersRange(StringListToDouble(myList)); - }*/ - if (getProxyPragaName(name_.toStdString()) == proxyHeight) { if (parameters->contains("fitting_function")) @@ -722,7 +703,7 @@ bool Project::loadParameters(QString parametersFileName) if (parameters->contains("fitting_parameters")) { - unsigned int nrParameters; + unsigned int nrParameters = NODATA; if (myProxy->getFittingFunctionName() == piecewiseTwo) nrParameters = 4; @@ -3224,7 +3205,6 @@ bool Project::loadProject() { errorType = ERROR_SETTINGS; errorString = "Load parameters failed.\n" + errorString; - logError(); return false; } diff --git a/project/project.h b/project/project.h index c8ef74d5..03f37e3c 100644 --- a/project/project.h +++ b/project/project.h @@ -181,7 +181,7 @@ void setProxyDEM(); void clearProxyDEM(); - bool checkProxy(const Crit3DProxy &myProxy, QString *error); + bool checkProxy(Crit3DProxy &myProxy, QString *error); bool addProxyToProject(std::vector proxyList, std::deque proxyActive, std::vector proxyOrder); void addProxyGridSeries(QString name_, std::vector gridNames, std::vector gridYears); void setCurrentDate(QDate myDate); diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 607b6c2a..4cd8aeaa 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -1,34 +1,9 @@ -/*! - CRITERIA3D - \copyright 2016 Fausto Tomei, Gabriele Antolini, Laura Costantini - Alberto Pistocchi, Marco Bittelli, Antonio Volta - You should have received a copy of the GNU General Public License - along with Nome-Programma. If not, see . - This file is part of CRITERIA3D. - CRITERIA3D has been developed under contract issued by A.R.P.A. Emilia-Romagna - CRITERIA3D is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - CRITERIA3D 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 Lesser General Public License for more details. - You should have received a copy of the /NU Lesser General Public License - along with CRITERIA3D. If not, see . - contacts: - fausto.tomei@gmail.com - ftomei@arpae.it -*/ - #include "meteo.h" #include "localProxyWidget.h" -#include "proxyWidget.h" #include "utilities.h" #include "interpolation.h" #include "spatialControl.h" #include "commonConstants.h" -#include "formInfo.h" #include "math.h" #include "furtherMathFunctions.h" diff --git a/proxyWidget/proxyWidget.cpp b/proxyWidget/proxyWidget.cpp index 1961b967..8f0d0e55 100644 --- a/proxyWidget/proxyWidget.cpp +++ b/proxyWidget/proxyWidget.cpp @@ -1,33 +1,9 @@ -/*! - CRITERIA3D - \copyright 2016 Fausto Tomei, Gabriele Antolini, Laura Costantini - Alberto Pistocchi, Marco Bittelli, Antonio Volta - You should have received a copy of the GNU General Public License - along with Nome-Programma. If not, see . - This file is part of CRITERIA3D. - CRITERIA3D has been developed under contract issued by A.R.P.A. Emilia-Romagna - CRITERIA3D is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - CRITERIA3D 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 Lesser General Public License for more details. - You should have received a copy of the /NU Lesser General Public License - along with CRITERIA3D. If not, see . - contacts: - fausto.tomei@gmail.com - ftomei@arpae.it -*/ - #include "meteo.h" #include "proxyWidget.h" #include "utilities.h" #include "interpolation.h" #include "spatialControl.h" #include "commonConstants.h" -#include "formInfo.h" #include "math.h" #include From 6f88c00d6c2ca361ef1b55fcc408b51a4d39fda0 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 1 Aug 2024 12:54:00 +0200 Subject: [PATCH 165/179] update 3D --- meteoWidget/meteoWidget.cpp | 92 ++++++++++++++++++------------------- meteoWidget/meteoWidget.h | 4 +- project/project.cpp | 7 ++- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/meteoWidget/meteoWidget.cpp b/meteoWidget/meteoWidget.cpp index 79d56abd..5324411c 100644 --- a/meteoWidget/meteoWidget.cpp +++ b/meteoWidget/meteoWidget.cpp @@ -64,7 +64,7 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe this->resize(1240, 700); this->setAttribute(Qt::WA_DeleteOnClose); - currentFreq = noFrequency; + _currentFrequency = noFrequency; QDate noDate = QDate(1800,1,1); currentDate = noDate; @@ -140,11 +140,11 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe } if (key.contains("DAILY")) { - currentFreq = daily; + _currentFrequency = daily; } else { - currentFreq = hourly; + _currentFrequency = hourly; } MapCSVDefault.insert(key,items); zeroLine = new QLineSeries(); @@ -207,7 +207,7 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe if (currentVariables.isEmpty() || (dailyVar != 0 && hourlyVar != 0)) { QMessageBox::information(nullptr, "Warning", "Wrong variables in Crit3DPlotDefault.csv"); - currentFreq = noFrequency; + _currentFrequency = noFrequency; currentVariables.clear(); nameLines.clear(); nameBar.clear(); @@ -293,19 +293,19 @@ Crit3DMeteoWidget::Crit3DMeteoWidget(bool isGrid_, QString projectPath, Crit3DMe firstDate->setMinimumWidth(firstDate->width()-firstDate->width()*0.3); lastDate->setMinimumWidth(lastDate->width()-lastDate->width()*0.3); - if (currentFreq == daily || currentFreq == noFrequency) + if (_currentFrequency == daily || _currentFrequency == noFrequency) { dailyButton->setEnabled(false); hourlyButton->setEnabled(true); monthlyButton->setEnabled(true); } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { hourlyButton->setEnabled(false); dailyButton->setEnabled(true); monthlyButton->setEnabled(true); } - else if (currentFreq == monthly) + else if (_currentFrequency == monthly) { monthlyButton->setEnabled(false); dailyButton->setEnabled(true); @@ -421,24 +421,24 @@ Crit3DMeteoWidget::~Crit3DMeteoWidget() } -void Crit3DMeteoWidget::setCurrentFrequency(frequencyType frequency) +void Crit3DMeteoWidget::setFrequency(frequencyType frequency) { - currentFreq = frequency; + _currentFrequency = frequency; // update gui - if (currentFreq == daily || currentFreq == noFrequency) + if (_currentFrequency == daily || _currentFrequency == noFrequency) { dailyButton->setEnabled(false); hourlyButton->setEnabled(true); monthlyButton->setEnabled(true); } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { hourlyButton->setEnabled(false); dailyButton->setEnabled(true); monthlyButton->setEnabled(true); } - else if (currentFreq == monthly) + else if (_currentFrequency == monthly) { monthlyButton->setEnabled(false); dailyButton->setEnabled(true); @@ -582,11 +582,11 @@ void Crit3DMeteoWidget::drawMeteoPoint(Crit3DMeteoPoint mp, bool isAppend) lastDate->setDate(currentDate); // draw period (31 days for daily, 3 days for hourly) - if (currentFreq == daily) + if (_currentFrequency == daily) { firstDate->setDate(currentDate.addDays(-30)); } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { firstDate->setDate(currentDate.addDays(-2)); } @@ -680,9 +680,9 @@ void Crit3DMeteoWidget::drawEnsemble() lastDate->setDate(currentDate); // draw period (31 days for daily, 3 days for hourly) - if (currentFreq == daily) + if (_currentFrequency == daily) firstDate->setDate(currentDate.addDays(-30)); - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) firstDate->setDate(currentDate.addDays(-2)); redraw(); @@ -2052,19 +2052,19 @@ void Crit3DMeteoWidget::showVar() { if (! isInitialized) return; - if (currentFreq == noFrequency) + if (_currentFrequency == noFrequency) { if (dailyButton->isChecked()) // dailyButton is pressed { - currentFreq = daily; + _currentFrequency = daily; } else if (hourlyButton->isChecked()) { - currentFreq = hourly; + _currentFrequency = hourly; } else if (monthlyButton->isChecked()) { - currentFreq = monthly; + _currentFrequency = monthly; } } QList allKeys = MapCSVStyles.keys(); @@ -2072,21 +2072,21 @@ void Crit3DMeteoWidget::showVar() QList allVar; for (int i = 0; idate().daysTo(lastDate->date()); QDate firstValidDate; - if (currentFreq == daily) + if (_currentFrequency == daily) { if (! firstDailyDate.isValid() || firstDailyDate.year() == 1800) return; firstValidDate = firstDailyDate; } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { if (! firstHourlyDate.isValid() || firstHourlyDate.year() == 1800) return; firstValidDate = firstHourlyDate; } - else if (currentFreq == monthly) + else if (_currentFrequency == monthly) { if (! firstMonthlyDate.isValid() || firstMonthlyDate.year() == 1800) return; @@ -2477,7 +2477,7 @@ void Crit3DMeteoWidget::shiftFollowing() int nDays = firstDate->date().daysTo(lastDate->date()); QDate lastValidDate; - if (currentFreq == daily) + if (_currentFrequency == daily) { if (! lastDailyDate.isValid() || lastDailyDate.year() == 1800) return; @@ -2509,7 +2509,7 @@ void Crit3DMeteoWidget::shiftFollowing() void Crit3DMeteoWidget::showTable() { - DialogMeteoTable meteoTable(meteoSettings, meteoPoints, firstDate->date(), lastDate->date(), currentFreq, currentVariables); + DialogMeteoTable meteoTable(meteoSettings, meteoPoints, firstDate->date(), lastDate->date(), _currentFrequency, currentVariables); } void Crit3DMeteoWidget::tooltipLineSeries(QPointF point, bool state) @@ -2608,18 +2608,18 @@ bool Crit3DMeteoWidget::computeTooltipLineSeries(QLineSeries *series, QPointF po if (!valueExist) { // missing data - if (currentFreq == daily) + if (_currentFrequency == daily) { QDate xDate = firstDate->date().addDays(doy); m_tooltip->setText(QString("%1 \n%2 nan ").arg(series->name()).arg(xDate.toString("MMM dd yyyy"))); } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { QDateTime xDate(firstDate->date(), QTime(0,0,0), Qt::UTC); xDate = xDate.addSecs(3600*doy); m_tooltip->setText(QString("%1 \n%2 nan ").arg(series->name()).arg(xDate.toString("MMM dd yyyy hh:mm"))); } - else if (currentFreq == monthly) + else if (_currentFrequency == monthly) { QDate xDate = firstDate->date().addMonths(doy); m_tooltip->setText(QString("%1 \n%2 nan ").arg(series->name()).arg(xDate.toString("MMM yyyy"))); @@ -2739,7 +2739,7 @@ bool Crit3DMeteoWidget::computeTooltipLineSeries(QLineSeries *series, QPointF po } - if (currentFreq == daily) + if (_currentFrequency == daily) { QDate xDate = firstDate->date().addDays(doy); for(int i = 0; i < series->count(); i++) @@ -2753,7 +2753,7 @@ bool Crit3DMeteoWidget::computeTooltipLineSeries(QLineSeries *series, QPointF po double value = series->at(doyRelative).y(); m_tooltip->setText(QString("%1 \n%2 %3 ").arg(series->name()).arg(xDate.toString("MMM dd yyyy")).arg(value, 0, 'f', 1)); } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { QDateTime xDate(firstDate->date(), QTime(0,0,0), Qt::UTC); xDate = xDate.addSecs(3600*doy); @@ -2768,7 +2768,7 @@ bool Crit3DMeteoWidget::computeTooltipLineSeries(QLineSeries *series, QPointF po double value = series->at(doyRelative).y(); m_tooltip->setText(QString("%1 \n%2 %3 ").arg(series->name()).arg(xDate.toString("MMM dd yyyy hh:mm")).arg(value, 0, 'f', 1)); } - else if (currentFreq == monthly) + else if (_currentFrequency == monthly) { QDate xDate = firstDate->date().addMonths(doy); for(int i = 0; i < series->count(); i++) @@ -2829,19 +2829,19 @@ void Crit3DMeteoWidget::tooltipBar(bool state, int index, QBarSet *barset) } QString valueStr; - if (currentFreq == daily) + if (_currentFrequency == daily) { QDate xDate = firstDate->date().addDays(index); valueStr = QString("%1 \n%2 %3 ").arg(xDate.toString("MMM dd yyyy")).arg(barset->label()).arg(barset->at(index), 0, 'f', 1); } - else if (currentFreq == hourly) + else if (_currentFrequency == hourly) { QDateTime xDate(firstDate->date(), QTime(0,0,0), Qt::UTC); xDate = xDate.addSecs(3600*index); valueStr = QString("%1 \n%2 %3 ").arg(xDate.toString("MMM dd yyyy hh:mm")).arg(barset->label()).arg(barset->at(index), 0, 'f', 1); } - else if (currentFreq == monthly) + else if (_currentFrequency == monthly) { QDate xDate = firstDate->date().addMonths(index); valueStr = QString("%1 \n%2 %3 ").arg(xDate.toString("MMM yyyy")).arg(barset->label()).arg(barset->at(index), 0, 'f', 1); diff --git a/meteoWidget/meteoWidget.h b/meteoWidget/meteoWidget.h index 2186dfea..d27e6c62 100644 --- a/meteoWidget/meteoWidget.h +++ b/meteoWidget/meteoWidget.h @@ -24,7 +24,7 @@ bool getIsEnsemble() { return isEnsemble; } void setNrMembers(int value) { nrMembers = value; } - void setCurrentFrequency(frequencyType frequency); + void setFrequency(frequencyType frequency); void setDailyRange(QDate firstDate, QDate lastDate); void setHourlyRange(QDate firstDate, QDate lastDate); @@ -46,7 +46,7 @@ QVector meteoPointsEnsemble; Crit3DMeteoSettings* meteoSettings; - frequencyType currentFreq; + frequencyType _currentFrequency; QDate firstDailyDate; QDate lastDailyDate; QDate firstHourlyDate; diff --git a/project/project.cpp b/project/project.cpp index b16288ef..5a172926 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2969,6 +2969,7 @@ frequencyType Project::getCurrentFrequency() const return currentFrequency; } + void Project::setCurrentFrequency(const frequencyType &value) { currentFrequency = value; @@ -3368,7 +3369,7 @@ void Project::showMeteoWidgetPoint(std::string idMeteoPoint, std::string namePoi QDateTime lastHourly = meteoPointsDbHandler->getLastDate(hourly, idMeteoPoint); bool hasHourlyData = !(firstHourly.isNull() || lastHourly.isNull()); - if (!hasDailyData && !hasHourlyData) + if (! hasDailyData && ! hasHourlyData) { logInfoGUI("No data."); return; @@ -3436,6 +3437,10 @@ void Project::showMeteoWidgetPoint(std::string idMeteoPoint, std::string namePoi if (hasHourlyData) { meteoWidgetPoint->setHourlyRange(firstHourly.date(), lastHourly.date()); + if (! hasDailyData) + { + meteoWidgetPoint->setFrequency(hourly); + } } meteoWidgetPoint->setCurrentDate(this->currentDate); From a7605b59553e866966ec3a273d23b45bc2d3a061 Mon Sep 17 00:00:00 2001 From: Gabriele Antolini Date: Thu, 1 Aug 2024 15:35:24 +0200 Subject: [PATCH 166/179] local proxy widget minors --- proxyWidget/localProxyWidget.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proxyWidget/localProxyWidget.cpp b/proxyWidget/localProxyWidget.cpp index 4cd8aeaa..181a0180 100644 --- a/proxyWidget/localProxyWidget.cpp +++ b/proxyWidget/localProxyWidget.cpp @@ -39,6 +39,10 @@ Crit3DLocalProxyWidget::Crit3DLocalProxyWidget(double x, double y, std::vectorsetPos(scenePos); chartView->scene()->addItem(weightLabel); weightLabels.push_back(weightLabel); From d03a7f2fabd9447174f1b6b2e87e20fdff67c834 Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 5 Aug 2024 20:13:10 +0200 Subject: [PATCH 167/179] update save output points --- dbMeteoGrid/dbMeteoGrid.cpp | 2 +- dbMeteoPoints/dbAggregationsHandler.cpp | 1 - outputPoints/dbOutputPointsHandler.cpp | 88 +++++++++++++++++++------ outputPoints/dbOutputPointsHandler.h | 26 +++++--- 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/dbMeteoGrid/dbMeteoGrid.cpp b/dbMeteoGrid/dbMeteoGrid.cpp index a39a9b2d..22f804c7 100644 --- a/dbMeteoGrid/dbMeteoGrid.cpp +++ b/dbMeteoGrid/dbMeteoGrid.cpp @@ -2501,7 +2501,7 @@ std::vector Crit3DMeteoGridDbHandler::loadGridDailyVar(QString *errorStr, // read last date qry.last(); - if (!getValue(qry.value(_tableDaily.fieldTime), &lastDateDB)) + if (! getValue(qry.value(_tableDaily.fieldTime), &lastDateDB)) { *errorStr = "Missing last date"; return dailyVarList; diff --git a/dbMeteoPoints/dbAggregationsHandler.cpp b/dbMeteoPoints/dbAggregationsHandler.cpp index 1b343b9f..731670b4 100644 --- a/dbMeteoPoints/dbAggregationsHandler.cpp +++ b/dbMeteoPoints/dbAggregationsHandler.cpp @@ -243,7 +243,6 @@ bool Crit3DAggregationsDbHandler::writePointProperties(int numZones, QString agg QSqlQuery qry(_db); for (int i = 1; i <= numZones; i++) - { QString id = QString::number(i) + "_" + aggrType; QString name = id; diff --git a/outputPoints/dbOutputPointsHandler.cpp b/outputPoints/dbOutputPointsHandler.cpp index ce6b0ab0..636add04 100644 --- a/outputPoints/dbOutputPointsHandler.cpp +++ b/outputPoints/dbOutputPointsHandler.cpp @@ -13,14 +13,10 @@ Crit3DOutputPointsDbHandler::Crit3DOutputPointsDbHandler(QString dbname_) { _db.close(); } - errorString = ""; _db = QSqlDatabase::addDatabase("QSQLITE", QUuid::createUuid().toString()); _db.setDatabaseName(dbname_); - if (! _db.open()) - { - errorString = _db.lastError().text(); - } + _db.open(); } @@ -126,26 +122,78 @@ bool Crit3DOutputPointsDbHandler::addCriteria3DColumn(const QString &tableName, bool Crit3DOutputPointsDbHandler::saveHourlyMeteoData(const QString &tableName, const QDateTime &myTime, const std::vector &varList, - const std::vector &values, + const std::vector &valuesList, QString &errorStr) { - if (varList.size() != values.size()) + if (varList.size() != valuesList.size()) { errorStr = "Error saving values: number of variables is different from values"; return false; } - QSqlQuery qry(_db); QString timeStr = myTime.toString("yyyy-MM-dd HH:mm:ss"); - QString queryString = QString("DELETE FROM '%1' WHERE DATE_TIME ='%2'").arg(tableName, timeStr); + QString queryString = QString("SELECT * FROM '%1' WHERE DATE_TIME='%2'").arg(tableName, timeStr); + QSqlQuery query(_db); + + if (! query.exec(queryString)) + { + errorStr = QString("Error in reading table: %1 \nTime: %2 \n%3") + .arg(tableName, timeStr, query.lastError().text()); + return false; + } + + query.last(); + int querySize = query.at() + 1; // SQLITE doesn't support SIZE + if (querySize > 0) + { + return saveHourlyMeteoData_update(tableName, timeStr, varList, valuesList, errorStr); + } + else + { + return saveHourlyMeteoData_insert(tableName, timeStr, varList, valuesList, errorStr); + } + +} + +bool Crit3DOutputPointsDbHandler::saveHourlyMeteoData_update(const QString &tableName, const QString timeStr, + const std::vector &varList, + const std::vector &values, + QString &errorStr) +{ + QList assignList; + for (unsigned int i = 0; i < varList.size(); i++) + { + QString fieldStr = QString::fromStdString(getMeteoVarName(varList[i])); + if (fieldStr.isEmpty()) + { + errorStr = QString("Error saving values in table:%1 \nMissing variable name").arg(tableName); + return false; + } + + QString valueStr = QString::number(values[i], 'f', 2); + + assignList.push_back("'" + fieldStr + "'=" + valueStr); + } + + QSqlQuery qry(_db); + QString queryString = QString("UPDATE '%1' SET %2 WHERE DATE_TIME = DATETIME('%3')").arg(tableName, assignList.join(','), timeStr); if (! qry.exec(queryString)) { - errorStr = QString("Error deleting values in table:%1 Time:%2\n%3") - .arg(tableName, timeStr, qry.lastError().text()); + errorStr = QString("Error saving values in table:%1 Time:%2\n%3") + .arg(tableName, timeStr, qry.lastError().text()); return false; } + return true; +} + + +bool Crit3DOutputPointsDbHandler::saveHourlyMeteoData_insert(const QString &tableName, const QString timeStr, + const std::vector &varList, + const std::vector &values, + QString &errorStr) +{ // field list QString fieldList = "'DATE_TIME'"; for (unsigned int i = 0; i < varList.size(); i++) @@ -157,23 +205,24 @@ bool Crit3DOutputPointsDbHandler::saveHourlyMeteoData(const QString &tableName, } else { - errorStr = "Error saving values: missing variable name."; + errorStr = QString("Error saving values in table:%1 \nMissing variable name").arg(tableName); return false; } } // values list QString valuesList = "'" + timeStr + "'"; - for (unsigned int i = 0; i < varList.size(); i++) + for (unsigned int i = 0; i < values.size(); i++) { valuesList += "," + QString::number(values[i], 'f', 2); } - queryString = QString("INSERT INTO '%1' (%2) VALUES (%3)").arg(tableName, fieldList, valuesList); + QSqlQuery qry(_db); + QString queryString = QString("INSERT INTO '%1' (%2) VALUES (%3)").arg(tableName, fieldList, valuesList); if (! qry.exec(queryString)) { errorStr = QString("Error saving values in table:%1 Time:%2\n%3") - .arg(tableName, timeStr, qry.lastError().text()); + .arg(tableName, timeStr, qry.lastError().text()); return false; } @@ -181,6 +230,7 @@ bool Crit3DOutputPointsDbHandler::saveHourlyMeteoData(const QString &tableName, } + // variableDepth [cm] bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &tableName, const QDateTime& myTime, const std::vector& values, @@ -190,8 +240,8 @@ bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &table const std::vector& factorOfSafetyDepth, QString &errorStr) { - int nrValues = waterContentDepth.size() + waterPotentialDepth.size() - + degreeOfSaturationDepth.size() + factorOfSafetyDepth.size(); + int nrValues = int(waterContentDepth.size() + waterPotentialDepth.size() + + degreeOfSaturationDepth.size() + factorOfSafetyDepth.size()); if (nrValues != int(values.size())) { @@ -210,7 +260,7 @@ bool Crit3DOutputPointsDbHandler::saveHourlyCriteria3D_Data(const QString &table QSqlQuery qry(_db); - QString queryString = QString("UPDATE '%1' SET %2 WHERE DATE_TIME ='%3'").arg(tableName, valueList.join(','), timeStr); + QString queryString = QString("UPDATE '%1' SET %2 WHERE DATE_TIME = DATETIME('%3')").arg(tableName, valueList.join(','), timeStr); if (! qry.exec(queryString)) { errorStr = QString("Error in query: " + queryString + "\n" + qry.lastError().text()); @@ -240,6 +290,6 @@ void Crit3DOutputPointsDbHandler::appendCriteria3DOutputValue(criteria3DVariable outputList.push_back(assignStr); } - firstIndex += depthList.size(); + firstIndex += int(depthList.size()); } diff --git a/outputPoints/dbOutputPointsHandler.h b/outputPoints/dbOutputPointsHandler.h index b53bf3ce..7007fbab 100644 --- a/outputPoints/dbOutputPointsHandler.h +++ b/outputPoints/dbOutputPointsHandler.h @@ -6,6 +6,7 @@ #endif #include + #include #include class Crit3DOutputPointsDbHandler @@ -14,14 +15,14 @@ explicit Crit3DOutputPointsDbHandler(QString dbname_); ~Crit3DOutputPointsDbHandler(); - QString getDbName() { - return _db.databaseName(); } + QString getDbName() + { return _db.databaseName(); } - QString getErrorString() { - return errorString; } + QString getErrorString() + { return _db.lastError().text(); } - bool isOpen() { - return _db.isOpen(); } + bool isOpen() + { return _db.isOpen(); } bool createTable(const QString &tableName, QString &errorStr); @@ -31,7 +32,7 @@ bool saveHourlyMeteoData(const QString &tableName, const QDateTime &myTime, const std::vector &varList, - const std::vector &values, QString &errorStr); + const std::vector &valuesList, QString &errorStr); bool saveHourlyCriteria3D_Data(const QString &tableName, const QDateTime& myTime, const std::vector& values, @@ -48,7 +49,16 @@ private: QSqlDatabase _db; - QString errorString; + + bool saveHourlyMeteoData_insert(const QString &tableName, const QString timeStr, + const std::vector &varList, + const std::vector &values, + QString &errorStr); + + bool saveHourlyMeteoData_update(const QString &tableName, const QString timeStr, + const std::vector &varList, + const std::vector &values, + QString &errorStr); }; From 84629b9d82b47eb345c14bf8ae41bbcac888d391 Mon Sep 17 00:00:00 2001 From: Caterina Toscano Date: Tue, 6 Aug 2024 09:13:02 +0200 Subject: [PATCH 168/179] cleanup and minor changes --- interpolation/interpolation.cpp | 43 ++++++--- interpolation/interpolation.h | 2 +- project/project.cpp | 151 ++++++++++++++++---------------- 3 files changed, 107 insertions(+), 89 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index acb95b2c..b17f01fa 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1465,19 +1465,33 @@ bool proxyValidityWeighted(std::vector &myPoints, return true; } -bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings) +bool setHeightFittingRange(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings) { if (mySettings->getMinMaxTemperature().empty()) return 0; + const double H0_MIN = -200; //height of inversion point (double piecewise) or first inversion point (triple piecewise) + const double H0_MAX = 5000; + const double DELTA_MIN = 300; //height difference between inversion points (for triple piecewise only) + const double DELTA_MAX = 1000; + const double SLOPE_MIN = 0.002; //ascending slope + const double SLOPE_MAX = 0.007; + const double INVSLOPE_MIN = -0.01; //inversion slope + const double INVSLOPE_MAX = -0.0015; + for (unsigned i=0; i < myCombination.getProxySize(); i++) if (myCombination.isProxyActive(i) == true) { if (getProxyPragaName(mySettings->getProxy(i)->getName()) == proxyHeight) { - double min = mySettings->getMinMaxTemperature()[0]; - double max = mySettings->getMinMaxTemperature()[1]; - + const double MIN_T = mySettings->getMinMaxTemperature()[0]; + const double MAX_T = mySettings->getMinMaxTemperature()[1]; + + /* + * following line allows to check if the function for elevation has been changed (GUI only) compared to the + * function read in the .ini file. if it hasn't been changed, only the minimum and maximum temperature get rewritten. + * otherwise appropriate parameters are loaded into the proxy (fittingParametersRange) + */ if (mySettings->getChosenElevationFunction() == mySettings->getProxy(i)->getFittingFunctionName()) { std::vector tempParam; @@ -1486,18 +1500,18 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati { if (mySettings->getChosenElevationFunction() == piecewiseTwo) { - tempParam[1] = min-2; - tempParam[5] = max+2; + tempParam[1] = MIN_T-2; + tempParam[5] = MAX_T+2; } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { - tempParam[1] = min-2; - tempParam[7] = max+2; + tempParam[1] = MIN_T-2; + tempParam[7] = MAX_T+2; } else if (mySettings->getChosenElevationFunction() == piecewiseThree) { - tempParam[1] = min-2; - tempParam[6] = max+2; + tempParam[1] = MIN_T-2; + tempParam[6] = MAX_T+2; } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } @@ -1508,17 +1522,20 @@ bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolati if (mySettings->getChosenElevationFunction() == piecewiseTwo) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseTwo); - tempParam = {-200, min-2, 0.002, -0.01, 5000, max+2, 0.01, -0.0015}; + tempParam = {H0_MIN, MIN_T-2, SLOPE_MIN, INVSLOPE_MIN, + H0_MAX, MAX_T+2, SLOPE_MAX, INVSLOPE_MAX}; } else if (mySettings->getChosenElevationFunction() == piecewiseThreeFree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThreeFree); - tempParam = {-200, min-2, 300, 0.002, -0.01, -0.01, 5000, max+2, 1000, 0.007, -0.0015, -0.0015}; + tempParam = {H0_MIN, MIN_T-2, DELTA_MIN, SLOPE_MIN, INVSLOPE_MIN, INVSLOPE_MIN, + H0_MAX, MAX_T+2, DELTA_MAX, SLOPE_MAX, INVSLOPE_MAX, INVSLOPE_MAX}; } else if (mySettings->getChosenElevationFunction() == piecewiseThree) { mySettings->getProxy(i)->setFittingFunctionName(piecewiseThree); - tempParam = {-200, min-2, 300, 0.002, -0.01, 5000, max+2, 1000, 0.007, -0.0015}; + tempParam = {H0_MIN, MIN_T-2, DELTA_MIN, SLOPE_MIN, INVSLOPE_MIN, + H0_MAX, MAX_T+2, DELTA_MAX, SLOPE_MAX, INVSLOPE_MAX}; } mySettings->getProxy(i)->setFittingParametersRange(tempParam); } diff --git a/interpolation/interpolation.h b/interpolation/interpolation.h index f4857765..88cbff1e 100644 --- a/interpolation/interpolation.h +++ b/interpolation/interpolation.h @@ -109,7 +109,7 @@ bool proxyValidityWeighted(std::vector &myPoints, int proxyPos, float stdDevThreshold, double &avg, double &stdDev); - bool setAllFittingRanges(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings); + bool setHeightFittingRange(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings); bool setAllFittingParameters_noRange(Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings, std::vector&)>>& myFunc, diff --git a/project/project.cpp b/project/project.cpp index e689cd12..fca7e538 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -201,6 +201,7 @@ void Project::setProxyDEM() bool Project::checkProxy(Crit3DProxy &myProxy, QString* error) { std::string name_ = myProxy.getName(); + QList myList; if (name_ == "") { @@ -216,6 +217,79 @@ bool Project::checkProxy(Crit3DProxy &myProxy, QString* error) return false; } + if (isHeight) + { + if (parameters->contains("fitting_function")) + { + std::string elevationFuction = parameters->value("fitting_function").toString().toStdString(); + if (fittingFunctionNames.find(elevationFuction) == fittingFunctionNames.end()) + { + errorString = "Unknown function for elevation. Remove the field from the .ini file or choose between: piecewise_two, triple_piecewise, free_triple_piecewise."; + return false; + } + else + myProxy.setFittingFunctionName(fittingFunctionNames.at(elevationFuction)); + + if (parameters->contains("fitting_parameters")) + { + unsigned int nrParameters = NODATA; + + if (myProxy.getFittingFunctionName() == piecewiseTwo) + nrParameters = 4; + else if (myProxy.getFittingFunctionName() == piecewiseThree) + nrParameters = 5; + else if (myProxy.getFittingFunctionName()== piecewiseThreeFree) + nrParameters = 6; + + myList = parameters->value("fitting_parameters").toStringList(); + if (myList.size() != nrParameters*2) + { + *error = "Wrong number of fitting parameters for proxy: " + QString::fromStdString(name_); + return false; + } + + myProxy.setFittingParametersRange(StringListToDouble(myList)); + } + } + else + { + if (parameters->contains("fitting_parameters")) + { + myList = parameters->value("fitting_parameters").toStringList(); + + if (myList.size() == 8) + myProxy.setFittingFunctionName(piecewiseTwo); + else if (myList.size() == 10) + myProxy.setFittingFunctionName(piecewiseThree); + else if (myList.size() == 12) + myProxy.setFittingFunctionName(piecewiseThreeFree); + else + { + *error = "Wrong number of fitting parameters for proxy: " + QString::fromStdString(name_); + return false; + } + myProxy.setFittingParametersRange(StringListToDouble(myList)); + } + } + } + else + { + myProxy.setFittingFunctionName(linear); + if(parameters->contains("fitting_parameters")) + { + unsigned int nrParameters = 2; + + myList = parameters->value("fitting_parameters").toStringList(); + if (myList.size() != nrParameters*2) + { + *error = "Wrong number of fitting parameters for proxy: " + QString::fromStdString(name_); + return false; + } + + myProxy.setFittingParametersRange(StringListToDouble(myList)); + } + } + return true; } @@ -688,79 +762,6 @@ bool Project::loadParameters(QString parametersFileName) if (parameters->contains("stddev_threshold")) myProxy->setStdDevThreshold(parameters->value("stddev_threshold").toFloat()); - if (getProxyPragaName(name_.toStdString()) == proxyHeight) - { - if (parameters->contains("fitting_function")) - { - std::string elevationFuction = parameters->value("fitting_function").toString().toStdString(); - if (fittingFunctionNames.find(elevationFuction) == fittingFunctionNames.end()) - { - errorString = "Unknown function for elevation. Remove the field from the .ini file or choose between: piecewise_two, triple_piecewise, free_triple_piecewise."; - return false; - } - else - myProxy->setFittingFunctionName(fittingFunctionNames.at(elevationFuction)); - - if (parameters->contains("fitting_parameters")) - { - unsigned int nrParameters = NODATA; - - if (myProxy->getFittingFunctionName() == piecewiseTwo) - nrParameters = 4; - else if (myProxy->getFittingFunctionName() == piecewiseThree) - nrParameters = 5; - else if (myProxy->getFittingFunctionName()== piecewiseThreeFree) - nrParameters = 6; - - myList = parameters->value("fitting_parameters").toStringList(); - if (myList.size() != nrParameters*2) - { - errorString = "Wrong number of fitting parameters for proxy: " + name_; - return false; - } - - myProxy->setFittingParametersRange(StringListToDouble(myList)); - } - } - else - { - if (parameters->contains("fitting_parameters")) - { - myList = parameters->value("fitting_parameters").toStringList(); - - if (myList.size() == 8) - myProxy->setFittingFunctionName(piecewiseTwo); - else if (myList.size() == 10) - myProxy->setFittingFunctionName(piecewiseThree); - else if (myList.size() == 12) - myProxy->setFittingFunctionName(piecewiseThreeFree); - else - { - errorString = "Wrong number of fitting parameters for proxy: " + name_; - return false; - } - myProxy->setFittingParametersRange(StringListToDouble(myList)); - } - } - } - else - { - myProxy->setFittingFunctionName(linear); - if(parameters->contains("fitting_parameters")) - { - unsigned int nrParameters = 2; - - myList = parameters->value("fitting_parameters").toStringList(); - if (myList.size() != nrParameters*2) - { - errorString = "Wrong number of fitting parameters for proxy: " + name_; - return false; - } - - myProxy->setFittingParametersRange(StringListToDouble(myList)); - } - } - if (! parameters->contains("active")) { errorString = "active not specified for proxy " + QString::fromStdString(myProxy->getName()); @@ -2412,7 +2413,7 @@ bool Project::interpolationDemLocalDetrending(meteoVariable myVar, const Crit3DT myRaster->initializeGrid(myHeader); myRaster->initializeParameters(myHeader); - if(!setAllFittingRanges(myCombination, &interpolationSettings)) + if(!setHeightFittingRange(myCombination, &interpolationSettings)) { errorString = "Error in function preInterpolation: \n couldn't set fitting ranges."; return false; @@ -2690,7 +2691,7 @@ bool Project::interpolationGrid(meteoVariable myVar, const Crit3DTime& myTime) proxyValues.resize(unsigned(interpolationSettings.getProxyNr())); if (interpolationSettings.getUseLocalDetrending()) - if(!setAllFittingRanges(myCombination, &interpolationSettings)) + if(!setHeightFittingRange(myCombination, &interpolationSettings)) { errorString = "Error in function preInterpolation: \n couldn't set fitting ranges."; return false; From 1eef8e2bbde567030b22fe82c0dda18f1ee70b8e Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 6 Aug 2024 19:09:34 +0200 Subject: [PATCH 169/179] fix elaboration interpolation --- interpolation/interpolation.cpp | 9 +++++-- interpolation/spatialControl.cpp | 42 ++++++++++++++++++-------------- interpolation/spatialControl.h | 2 +- meteo/meteo.cpp | 4 +++ project/project.cpp | 10 +++----- 5 files changed, 40 insertions(+), 27 deletions(-) diff --git a/interpolation/interpolation.cpp b/interpolation/interpolation.cpp index b17f01fa..69691eb6 100644 --- a/interpolation/interpolation.cpp +++ b/interpolation/interpolation.cpp @@ -1160,6 +1160,7 @@ bool isThermal(meteoVariable myVar) myVar == dailyAirTemperatureAvg || myVar == dailyAirTemperatureMax || myVar == dailyAirTemperatureMin || + myVar == dailyReferenceEvapotranspirationHS || myVar == elaboration ) return true; else @@ -1174,6 +1175,7 @@ bool getUseDetrendingVar(meteoVariable myVar) myVar == dailyAirTemperatureAvg || myVar == dailyAirTemperatureMax || myVar == dailyAirTemperatureMin || + myVar == dailyReferenceEvapotranspirationHS || myVar == elaboration ) return true; @@ -1344,6 +1346,7 @@ bool regressionOrography(std::vector &myPoints, } } + void detrending(std::vector &myPoints, Crit3DProxyCombination myCombination, Crit3DInterpolationSettings* mySettings, Crit3DClimateParameters* myClimate, meteoVariable myVar, Crit3DTime myTime) @@ -2256,7 +2259,7 @@ void topographicDistanceOptimize(meteoVariable myVar, mySettings->setTopoDist_Kh(kh); if (computeResiduals(myVar, myMeteoPoints, nrMeteoPoints, interpolationPoints, mySettings, meteoSettings, true, true)) { - avgError = computeErrorCrossValidation(myVar, myMeteoPoints, nrMeteoPoints, myTime, meteoSettings); + avgError = computeErrorCrossValidation(myMeteoPoints, nrMeteoPoints); if (isEqual(bestError, NODATA) || avgError < bestError) { bestError = avgError; @@ -2303,7 +2306,7 @@ void optimalDetrending(meteoVariable myVar, Crit3DMeteoPoint* &myMeteoPoints, in if (computeResiduals(myVar, myMeteoPoints, nrMeteoPoints, interpolationPoints, mySettings, meteoSettings, true, true)) { - avgError = computeErrorCrossValidation(myVar, myMeteoPoints, nrMeteoPoints, myTime, meteoSettings); + avgError = computeErrorCrossValidation(myMeteoPoints, nrMeteoPoints); if (! isEqual(avgError, NODATA) && (isEqual(minError, NODATA) || avgError < minError)) { minError = avgError; @@ -2367,7 +2370,9 @@ bool preInterpolation(std::vector &myPoints, Crit } if (mySettings->getUseTD() && getUseTdVar(myVar)) + { topographicDistanceOptimize(myVar, myMeteoPoints, nrMeteoPoints, myPoints, mySettings, meteoSettings, myTime); + } return true; } diff --git a/interpolation/spatialControl.cpp b/interpolation/spatialControl.cpp index f7834caf..932e0130 100644 --- a/interpolation/spatialControl.cpp +++ b/interpolation/spatialControl.cpp @@ -84,9 +84,6 @@ bool computeResiduals(meteoVariable myVar, Crit3DMeteoPoint* meteoPoints, int nr if (myVar == noMeteoVar) return false; - float myValue, interpolatedValue; - interpolatedValue = NODATA; - myValue = NODATA; std::vector myProxyValues; bool isValid; @@ -101,58 +98,67 @@ bool computeResiduals(meteoVariable myVar, Crit3DMeteoPoint* meteoPoints, int nr if (isValid && meteoPoints[i].quality == quality::accepted) { - myValue = meteoPoints[i].currentValue; + float myValue = meteoPoints[i].currentValue; - interpolatedValue = interpolate(interpolationPoints, settings, meteoSettings, myVar, + float interpolatedValue = interpolate(interpolationPoints, settings, meteoSettings, myVar, float(meteoPoints[i].point.utm.x), float(meteoPoints[i].point.utm.y), float(meteoPoints[i].point.z), myProxyValues, false); - if ( myVar == precipitation - || myVar == dailyPrecipitation) + if ( myVar == precipitation || myVar == dailyPrecipitation) { if (myValue != NODATA) - if (myValue < meteoSettings->getRainfallThreshold()) myValue=0.; + { + if (myValue < meteoSettings->getRainfallThreshold()) + myValue=0.; + } if (interpolatedValue != NODATA) - if (interpolatedValue < meteoSettings->getRainfallThreshold()) interpolatedValue=0.; + { + if (interpolatedValue < meteoSettings->getRainfallThreshold()) + interpolatedValue=0.; + } } // TODO derived var if ((interpolatedValue != NODATA) && (myValue != NODATA)) + { meteoPoints[i].residual = interpolatedValue - myValue; + } } } return true; } -float computeErrorCrossValidation(meteoVariable myVar, Crit3DMeteoPoint* myPoints, int nrMeteoPoints, const Crit3DTime& myTime, Crit3DMeteoSettings* meteoSettings) + +float computeErrorCrossValidation(Crit3DMeteoPoint* myPoints, int nrMeteoPoints) { std::vector obsValues, estValues; - float myValue, myEstimate, myResidual; for (int i=0; i < nrMeteoPoints; i++) { if (myPoints[i].active) { - myValue = myPoints[i].getMeteoPointValue(myTime, myVar, meteoSettings); - myResidual = myPoints[i].residual; + float value = myPoints[i].currentValue; + float residual = myPoints[i].residual; - if (myValue != NODATA && myResidual != NODATA) + if (value != NODATA && residual != NODATA) { - myEstimate = myValue + myResidual; - obsValues.push_back(myValue); - estValues.push_back(myEstimate); + obsValues.push_back(value); + estValues.push_back(value + residual); } } } if (obsValues.size() > 0) + { return statistics::meanAbsoluteError(obsValues, estValues); - else return NODATA; + } + else + return NODATA; } diff --git a/interpolation/spatialControl.h b/interpolation/spatialControl.h index 1cb2d7e9..347efdb8 100644 --- a/interpolation/spatialControl.h +++ b/interpolation/spatialControl.h @@ -31,7 +31,7 @@ bool computeResiduals(meteoVariable myVar, Crit3DMeteoPoint* meteoPoints, int nrMeteoPoints, std::vector &interpolationPoints, Crit3DInterpolationSettings* settings, Crit3DMeteoSettings* meteoSettings, bool excludeOutsideDem, bool excludeSupplemental); - float computeErrorCrossValidation(meteoVariable myVar, Crit3DMeteoPoint *myPoints, int nrMeteoPoints, const Crit3DTime& myTime, Crit3DMeteoSettings *meteoSettings); + float computeErrorCrossValidation(Crit3DMeteoPoint *myPoints, int nrMeteoPoints); bool spatialQualityControl(meteoVariable myVar, Crit3DMeteoPoint* meteoPoints, int nrMeteoPoints, Crit3DInterpolationSettings *settings, Crit3DMeteoSettings* meteoSettings, diff --git a/meteo/meteo.cpp b/meteo/meteo.cpp index 21709b86..df096947 100644 --- a/meteo/meteo.cpp +++ b/meteo/meteo.cpp @@ -927,6 +927,10 @@ std::string getVariableString(meteoVariable myVar) else if (myVar == leafAreaIndex) return "Leaf area index (m2 m-2)"; + else if (myVar == elaboration) + return "Elaboration"; + else if (myVar == anomaly) + return "Anomaly"; else if (myVar == noMeteoTerrain) return "Elevation (m)"; else diff --git a/project/project.cpp b/project/project.cpp index fca7e538..dadd9e02 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -2213,13 +2213,11 @@ bool Project::computeStatisticsCrossValidation(Crit3DTime myTime, meteoVariable std::vector obs; std::vector pre; - float value; - for (int i = 0; i < nrMeteoPoints; i++) { if (meteoPoints[i].active) { - value = meteoPoints[i].getMeteoPointValue(myTime, myVar, meteoSettings); + float value = meteoPoints[i].currentValue; if (! isEqual(value, NODATA) && ! isEqual(meteoPoints[i].residual, NODATA)) { @@ -2264,11 +2262,11 @@ bool Project::interpolationCv(meteoVariable myVar, const Crit3DTime& myTime, cro } if (myVar == dailyGlobalRadiation || + myVar == globalIrradiance || myVar == dailyLeafWetness || myVar == dailyWindVectorDirectionPrevailing || myVar == dailyWindVectorIntensityAvg || - myVar == dailyWindVectorIntensityMax || - myVar == globalIrradiance) + myVar == dailyWindVectorIntensityMax ) { logError("Cross validation is not available for " + QString::fromStdString(getVariableString(myVar))); return false; @@ -2278,7 +2276,7 @@ bool Project::interpolationCv(meteoVariable myVar, const Crit3DTime& myTime, cro std::string errorStdStr; // check quality and pass data to interpolation - if (!checkAndPassDataToInterpolation(quality, myVar, meteoPoints, nrMeteoPoints, myTime, + if (! checkAndPassDataToInterpolation(quality, myVar, meteoPoints, nrMeteoPoints, myTime, &qualityInterpolationSettings, &interpolationSettings, meteoSettings, &climateParameters, interpolationPoints, checkSpatialQuality, errorStdStr)) From f90e444cf09c62968bef515bfbe5678be8149925 Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 6 Aug 2024 20:15:56 +0200 Subject: [PATCH 170/179] fix crop reset --- crop/crop.cpp | 2 +- crop/crop.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crop/crop.cpp b/crop/crop.cpp index d89405dc..5bdd9fb4 100644 --- a/crop/crop.cpp +++ b/crop/crop.cpp @@ -49,7 +49,7 @@ Crit3DCrop::Crit3DCrop() void Crit3DCrop::clear() { idCrop = ""; - type = HERBACEOUS_ANNUAL; + type = BARESOIL; roots.clear(); diff --git a/crop/crop.h b/crop/crop.h index 29c32389..4619c432 100644 --- a/crop/crop.h +++ b/crop/crop.h @@ -12,7 +12,7 @@ #endif enum speciesType {HERBACEOUS_ANNUAL, HERBACEOUS_PERENNIAL, HORTICULTURAL, GRASS, TREE, FALLOW, FALLOW_ANNUAL, BARESOIL}; - #define NR_CROP_SPECIES 7 + #define NR_CROP_SPECIES 8 /*! * \brief The Crit3DCrop class From 5c7ee2e53309a65ab97df7252b31a65cc702efba Mon Sep 17 00:00:00 2001 From: ftomei Date: Tue, 6 Aug 2024 20:18:19 +0200 Subject: [PATCH 171/179] update --- crop/crop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crop/crop.h b/crop/crop.h index 29c32389..4619c432 100644 --- a/crop/crop.h +++ b/crop/crop.h @@ -12,7 +12,7 @@ #endif enum speciesType {HERBACEOUS_ANNUAL, HERBACEOUS_PERENNIAL, HORTICULTURAL, GRASS, TREE, FALLOW, FALLOW_ANNUAL, BARESOIL}; - #define NR_CROP_SPECIES 7 + #define NR_CROP_SPECIES 8 /*! * \brief The Crit3DCrop class From afa3c7684703398c4a56462450f0d66fda58a795 Mon Sep 17 00:00:00 2001 From: ftomei Date: Wed, 7 Aug 2024 18:34:01 +0200 Subject: [PATCH 172/179] fix missing dataset in download --- pragaProject/pragaProject.cpp | 77 ++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index 8d8febd3..6e846857 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -1539,17 +1539,21 @@ bool PragaProject::downloadDailyDataArkimet(QList variables, bool prec0 id = QString::fromStdString(meteoPoints[i].id); dataset = QString::fromStdString(meteoPoints[i].dataset); - if (!datasetList.contains(dataset)) + // if the point doesn't have dataset, it is not downloaded from arkimet + if (! dataset.isEmpty()) { - datasetList << dataset; - QList myList; - myList << id; - idList.append(myList); - } - else - { - index = datasetList.indexOf(dataset); - idList[index].append(id); + if (! datasetList.contains(dataset)) + { + datasetList << dataset; + QList myList; + myList << id; + idList.append(myList); + } + else + { + index = datasetList.indexOf(dataset); + idList[index].append(id); + } } } } @@ -1566,23 +1570,27 @@ bool PragaProject::downloadDailyDataArkimet(QList variables, bool prec0 QDate date1 = startDate; QDate date2 = std::min(date1.addDays(MAXDAYS_DOWNLOAD_DAILY), endDate); - while (date1 <= endDate) + bool isOk = true; + while (date1 <= endDate && isOk) { - if (! myDownload->downloadDailyData(date1, date2, datasetList[i], idList[i], arkIdVar, prec0024, errorString)) + if (showInfo) { - return false; + updateProgressBar(startDate.daysTo(date2) + 1); } - if (showInfo) + isOk = myDownload->downloadDailyData(date1, date2, datasetList[i], idList[i], arkIdVar, prec0024, errorString); + if (! isOk) { - updateProgressBar(startDate.daysTo(date2) + 1); + logError(); + errorString = ""; } date1 = date2.addDays(1); date2 = std::min(date1.addDays(MAXDAYS_DOWNLOAD_DAILY), endDate); } - if (showInfo) closeProgressBar(); + if (showInfo) + closeProgressBar(); } delete myDownload; @@ -1615,22 +1623,26 @@ bool PragaProject::downloadHourlyDataArkimet(QList variables, QDate sta bool isSelection = isSelectionPointsActive(meteoPoints, nrMeteoPoints); for( int i=0; i < nrMeteoPoints; i++ ) { - if (!isSelection || meteoPoints[i].selected) + if (! isSelection || meteoPoints[i].selected) { id = QString::fromStdString(meteoPoints[i].id); dataset = QString::fromStdString(meteoPoints[i].dataset); - if (! datasetList.contains(dataset)) - { - datasetList << dataset; - QList myList; - myList << id; - idList.append(myList); - } - else + // if the point doesn't have dataset, it is not downloaded from arkimet + if (! dataset.isEmpty()) { - index = datasetList.indexOf(dataset); - idList[index].append(id); + if (! datasetList.contains(dataset)) + { + datasetList << dataset; + QList myList; + myList << id; + idList.append(myList); + } + else + { + index = datasetList.indexOf(dataset); + idList[index].append(id); + } } } } @@ -1646,17 +1658,19 @@ bool PragaProject::downloadHourlyDataArkimet(QList variables, QDate sta { setProgressBar("Download hourly data from: " + startDate.toString("yyyy-MM-dd") + " to:" + endDate.toString("yyyy-MM-dd") + " dataset:" + datasetList[i], nrDays); } - while (date1 <= endDate) + bool isOk = true; + while (date1 <= endDate && isOk) { if (showInfo) { updateProgressBar(startDate.daysTo(date2) + 1); } - errorString = ""; - if (! myDownload->downloadHourlyData(date1, date2, datasetList[i], idList[i], arkIdVar, errorString)) + isOk = myDownload->downloadHourlyData(date1, date2, datasetList[i], idList[i], arkIdVar, errorString); + if (! isOk) { - updateProgressBarText("NO DATA: " + errorString); + updateProgressBarText(errorString); + errorString = ""; } date1 = date2.addDays(1); @@ -1668,7 +1682,6 @@ bool PragaProject::downloadHourlyDataArkimet(QList variables, QDate sta } } - delete myDownload; return true; } From 3b9c7b0258c3c66693dfa37ff9ddeefcb077a906 Mon Sep 17 00:00:00 2001 From: ftomei Date: Thu, 8 Aug 2024 16:06:47 +0200 Subject: [PATCH 173/179] updat epond --- meteo/meteo.h | 2 +- soilFluxes3D/boundary.cpp | 10 ++- soilFluxes3D/header/soilFluxes3D.h | 26 ++++--- soilFluxes3D/header/types.h | 33 ++++---- soilFluxes3D/soilFluxes3D.cpp | 117 ++++++++++++++++++++--------- soilFluxes3D/water.cpp | 3 +- 6 files changed, 123 insertions(+), 68 deletions(-) diff --git a/meteo/meteo.h b/meteo/meteo.h index b57f8126..31279554 100644 --- a/meteo/meteo.h +++ b/meteo/meteo.h @@ -108,7 +108,7 @@ enum criteria3DVariable {volumetricWaterContent, waterTotalPotential, waterMatricPotential, availableWaterContent, degreeOfSaturation, soilTemperature, soilSurfaceMoisture, bottomDrainage, waterDeficit, waterInflow, waterOutflow, - factorOfSafety, minimumFactorOfSafety}; + factorOfSafety, minimumFactorOfSafety, surfacePond}; const std::map MapDailyMeteoVar = { diff --git a/soilFluxes3D/boundary.cpp b/soilFluxes3D/boundary.cpp index 270b7dbc..c41e7d7e 100644 --- a/soilFluxes3D/boundary.cpp +++ b/soilFluxes3D/boundary.cpp @@ -195,8 +195,9 @@ double getSurfaceWaterFraction(int i) return 0.0; else { - double h = MAXVALUE(nodeListPtr[i].H - double(nodeListPtr[i].z), 0); - return 1.0 - MAXVALUE(0.0, nodeListPtr[i].Soil->Pond - h) / nodeListPtr[i].Soil->Pond; + double h = std::max(nodeListPtr[i].H - nodeListPtr[i].z, 0.); // [m] + double h0 = std::max(double(nodeListPtr[i].pond), 0.001); // [m] + return h / h0; } } @@ -251,8 +252,9 @@ void updateBoundaryWater (double deltaT) if (nodeListPtr[i].boundary->type == BOUNDARY_RUNOFF) { double avgH = (nodeListPtr[i].H + nodeListPtr[i].oldH) * 0.5; // [m] + // Surface water available for runoff [m] - double hs = MAXVALUE(avgH - (nodeListPtr[i].z + nodeListPtr[i].Soil->Pond), 0.0); + double hs = MAXVALUE(avgH - (nodeListPtr[i].z + nodeListPtr[i].pond), 0.); if (hs > EPSILON_METER) { double maxFlow = (hs * nodeListPtr[i].volume_area) / deltaT; // [m3 s-1] maximum flow available during the time step @@ -383,7 +385,7 @@ void updateBoundaryWater (double deltaT) flow = weight * pressureFlow + (1. - weight) * ManningFlow; } - else if (waterLevel > nodeListPtr[i].Soil->Pond) + else if (waterLevel > nodeListPtr[i].pond) { // open channel flow double boundaryArea = myCulvert.width * waterLevel; // [m^2] diff --git a/soilFluxes3D/header/soilFluxes3D.h b/soilFluxes3D/header/soilFluxes3D.h index 9c8ebd07..d9724bc9 100644 --- a/soilFluxes3D/header/soilFluxes3D.h +++ b/soilFluxes3D/header/soilFluxes3D.h @@ -45,8 +45,9 @@ __EXTERN int DLL_EXPORT __STDCALL setNodeSoil(long nodeIndex, int soilIndex, int horizonIndex); // SURFACE - __EXTERN int DLL_EXPORT __STDCALL setSurfaceProperties(int surfaceIndex, double Roughness, double minWaterLevelRunoff); + __EXTERN int DLL_EXPORT __STDCALL setSurfaceProperties(int surfaceIndex, double Roughness); __EXTERN int DLL_EXPORT __STDCALL setNodeSurface(long nodeIndex, int surfaceIndex); + __EXTERN int DLL_EXPORT __STDCALL setNodePond(long nodeIndex, float pond); // WATER __EXTERN int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, int conductivityMeanType, float conductivityHorizVertRatio); @@ -57,22 +58,23 @@ __EXTERN int DLL_EXPORT __STDCALL setPrescribedTotalPotential(long index, double prescribedTotalPotential); __EXTERN int DLL_EXPORT __STDCALL setWaterSinkSource(long index, double sinkSource); - __EXTERN double DLL_EXPORT __STDCALL getWaterContent(long index); - __EXTERN double DLL_EXPORT __STDCALL getAvailableWaterContent(long index); + __EXTERN double DLL_EXPORT __STDCALL getWaterContent(long nodeIndex); + __EXTERN double DLL_EXPORT __STDCALL getAvailableWaterContent(long nodeIndex); __EXTERN double DLL_EXPORT __STDCALL getWaterDeficit(long index, double fieldCapacity); __EXTERN double DLL_EXPORT __STDCALL getTotalWaterContent(); - __EXTERN double DLL_EXPORT __STDCALL getDegreeOfSaturation(long index); - __EXTERN double DLL_EXPORT __STDCALL getBoundaryWaterFlow(long index); + __EXTERN double DLL_EXPORT __STDCALL getDegreeOfSaturation(long nodeIndex); + __EXTERN double DLL_EXPORT __STDCALL getBoundaryWaterFlow(long nodeIndex); __EXTERN double DLL_EXPORT __STDCALL getBoundaryWaterSumFlow(int boundaryType); - __EXTERN double DLL_EXPORT __STDCALL getMatricPotential(long index); - __EXTERN double DLL_EXPORT __STDCALL getTotalPotential(long index); + __EXTERN double DLL_EXPORT __STDCALL getMatricPotential(long nodeIndex); + __EXTERN double DLL_EXPORT __STDCALL getTotalPotential(long nodeIndex); __EXTERN double DLL_EXPORT __STDCALL getWaterMBR(); - __EXTERN double DLL_EXPORT __STDCALL getWaterConductivity(long index); - __EXTERN double DLL_EXPORT __STDCALL getWaterFlow(long index, short direction); - __EXTERN double DLL_EXPORT __STDCALL getSumLateralWaterFlow(long n); - __EXTERN double DLL_EXPORT __STDCALL getSumLateralWaterFlowIn(long n); - __EXTERN double DLL_EXPORT __STDCALL getSumLateralWaterFlowOut(long n); + __EXTERN double DLL_EXPORT __STDCALL getWaterConductivity(long nodeIndex); + __EXTERN double DLL_EXPORT __STDCALL getWaterFlow(long nodeIndex, short direction); + __EXTERN double DLL_EXPORT __STDCALL getSumLateralWaterFlow(long nodeIndex); + __EXTERN double DLL_EXPORT __STDCALL getSumLateralWaterFlowIn(long nodeIndex); + __EXTERN double DLL_EXPORT __STDCALL getSumLateralWaterFlowOut(long nodeIndex); __EXTERN double DLL_EXPORT __STDCALL getWaterStorage(); + __EXTERN float DLL_EXPORT __STDCALL getPond(long nodeIndex); // HEAT __EXTERN int DLL_EXPORT __STDCALL setHeatSinkSource(long nodeIndex, double myHeatFlow); diff --git a/soilFluxes3D/header/types.h b/soilFluxes3D/header/types.h index ee72271b..1d4bfaf5 100644 --- a/soilFluxes3D/header/types.h +++ b/soilFluxes3D/header/types.h @@ -8,6 +8,8 @@ #include "extra.h" #endif + #include "commonConstants.h" + struct Tboundary { short type; @@ -53,9 +55,9 @@ struct TlinkedNode { - long index; /*!< index of linked elements */ - float area; /*!< interface area [m^2] */ - float sumFlow; /*!< [m^3] sum of flow(i,j) */ + long index; /*!< index of linked elements */ + float area; /*!< interface area [m^2] */ + float sumFlow; /*!< [m3] sum of flow(i,j) */ TCrit3DLinkedNodeExtra* linkedExtra; /*!< extra variables for heat flux */ }; @@ -63,18 +65,17 @@ struct Tsoil { - double VG_alpha; /*!< [m^-1] Van Genutchen alpha parameter */ + double VG_alpha; /*!< [m-1] Van Genutchen alpha parameter */ double VG_n; /*!< [-] Van Genutchen n parameter */ double VG_m; /*!< [-] Van Genutchen m parameter ]0. , 1.[ */ double VG_he; /*!< [m] air-entry potential for modified VG formulation */ double VG_Sc; /*!< [-] reduction factor for modified VG formulation */ - double Theta_s; /*!< [m^3/m^3] saturated water content */ - double Theta_r; /*!< [m^3/m^3] residual water content */ - double K_sat; /*!< [m/sec] saturated hydraulic conductivity */ + double Theta_s; /*!< [m3 m-3] saturated water content */ + double Theta_r; /*!< [m3 m-3] residual water content */ + double K_sat; /*!< [m sec-1] saturated hydraulic conductivity */ double Mualem_L; /*!< [-] Mualem tortuosity parameter */ - double Roughness; /*!< [s/m^0.33] surface: Manning roughness */ - double Pond; /*!< [m] surface: height of immobilized water */ + double Roughness; /*!< [s m-1/3] surface: Manning roughness */ //for heat double organicMatter; /*!< [-] fraction of organic matter */ @@ -85,18 +86,20 @@ struct TCrit3Dnode { double Se; /*!< [-] degree of saturation */ - double k; /*!< [m s^-1] soil water conductivity */ + double k; /*!< [m s-1] soil water conductivity */ double H; /*!< [m] pressure head */ double oldH; /*!< [m] previous pressure head */ double bestH; /*!< [m] pressure head of best iteration */ - double waterSinkSource; /*!< [m^3 s^-1] water sink source */ - double Qw; /*!< [m^3 s^-1] water flow */ + double waterSinkSource; /*!< [m3 s-1] water sink source */ + double Qw; /*!< [m3 s-1] water flow */ - double volume_area; /*!< [m^3] sub-surface: volume of voxel */ - /*!< [m^2] surface: area of voxel */ + double volume_area; /*!< [m3] sub-surface: volume of voxel */ + /*!< [m2] surface: area of voxel */ float x, y; /*!< [m] coordinates of the center of the voxel */ double z; /*!< [m] heigth of the center of the voxel */ + float pond; /*!< [m] only surface: height of immobilized water */ + Tsoil *Soil; /*!< soil pointer */ Tboundary *boundary; /*!< boundary pointer */ TlinkedNode up; /*!< upper link */ @@ -133,7 +136,7 @@ long index = NOLINK; double width; /*!< [m] */ double height; /*!< [m] */ - double roughness; /*!< [s m-1/3] */ + double roughness; /*!< [s m-1/3] Manning roughness */ double slope; /*!< [-] */ }; diff --git a/soilFluxes3D/soilFluxes3D.cpp b/soilFluxes3D/soilFluxes3D.cpp index 4cb717a9..a46aa653 100644 --- a/soilFluxes3D/soilFluxes3D.cpp +++ b/soilFluxes3D/soilFluxes3D.cpp @@ -241,6 +241,14 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, nodeListPtr[myIndex].volume_area = volume_or_area; /*!< area on surface elements, volume on sub-surface */ nodeListPtr[myIndex].isSurface = isSurface; + if (isSurface) + { + nodeListPtr[myIndex].pond = 0.0001f; // [m] + } + else + { + nodeListPtr[myIndex].pond = NODATA; + } nodeListPtr[myIndex].waterSinkSource = 0.; @@ -344,7 +352,26 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, nodeListPtr[nodeIndex].Soil = &Surface_List[surfaceIndex]; - return(CRIT3D_OK); + return CRIT3D_OK; + } + + + /*! + * \brief setNodePond + * \param nodeIndex + * \param pond [m] + * \return OK/ERROR + */ + int DLL_EXPORT __STDCALL setNodePond(long nodeIndex, float pond) + { + if (nodeListPtr == nullptr) + return MEMORY_ERROR; + if (nodeIndex < 0 || (! nodeListPtr[nodeIndex].isSurface)) + return INDEX_ERROR; + + nodeListPtr[nodeIndex].pond = pond; + + return CRIT3D_OK; } @@ -417,16 +444,15 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, } - int DLL_EXPORT __STDCALL setSurfaceProperties(int surfaceIndex, double roughness, double surfacePond) + int DLL_EXPORT __STDCALL setSurfaceProperties(int surfaceIndex, double roughness) { - if (roughness < 0 || surfacePond < 0) + if (roughness < 0) return PARAMETER_ERROR; if (surfaceIndex > int(Surface_List.size()-1)) Surface_List.resize(surfaceIndex+1); Surface_List[surfaceIndex].Roughness = roughness; - Surface_List[surfaceIndex].Pond = surfacePond; return CRIT3D_OK; } @@ -592,6 +618,25 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, } + /*! + * \brief getPond + * \param nodeIndex + * \return surface maximum pond [m] + */ + float DLL_EXPORT __STDCALL getPond(long nodeIndex) + { + if (nodeListPtr == nullptr) + return MEMORY_ERROR; + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) + return INDEX_ERROR; + + if (! nodeListPtr[nodeIndex].isSurface) + return INDEX_ERROR; + + return nodeListPtr[nodeIndex].pond; + } + + /*! * \brief getWaterContent * \param nodeIndex @@ -728,7 +773,7 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, double DLL_EXPORT __STDCALL getTotalPotential(long nodeIndex) { if (nodeListPtr == nullptr) return(MEMORY_ERROR); - if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) return(INDEX_ERROR); + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) return(INDEX_ERROR); return (nodeListPtr[nodeIndex].H); } @@ -736,22 +781,22 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief getWaterFlow - * \param n + * \param nodeIndex * \param direction * \return maximum integrated flow in the requested direction [m^3] */ - double DLL_EXPORT __STDCALL getWaterFlow(long n, short direction) + double DLL_EXPORT __STDCALL getWaterFlow(long nodeIndex, short direction) { if (nodeListPtr == nullptr) return MEMORY_ERROR; - if ((n < 0) || (n >= myStructure.nrNodes)) return INDEX_ERROR; + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) return INDEX_ERROR; double maxFlow = 0.0; switch (direction) { case UP: - if (nodeListPtr[n].up.index != NOLINK) + if (nodeListPtr[nodeIndex].up.index != NOLINK) { - return nodeListPtr[n].up.sumFlow; + return nodeListPtr[nodeIndex].up.sumFlow; } else { @@ -759,9 +804,9 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, } case DOWN: - if (nodeListPtr[n].down.index != NOLINK) + if (nodeListPtr[nodeIndex].down.index != NOLINK) { - return nodeListPtr[n].down.sumFlow; + return nodeListPtr[nodeIndex].down.sumFlow; } else { @@ -771,10 +816,10 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, case LATERAL: // return maximum lateral flow for (short i = 0; i < myStructure.nrLateralLinks; i++) - if (nodeListPtr[n].lateral[i].index != NOLINK) - if (fabs(nodeListPtr[n].lateral[i].sumFlow) > maxFlow) + if (nodeListPtr[nodeIndex].lateral[i].index != NOLINK) + if (fabs(nodeListPtr[nodeIndex].lateral[i].sumFlow) > maxFlow) { - maxFlow = nodeListPtr[n].lateral[i].sumFlow; + maxFlow = nodeListPtr[nodeIndex].lateral[i].sumFlow; } return maxFlow; @@ -787,19 +832,19 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief getSumLateralWaterFlow - * \param n + * \param nodeIndex * \return integrated lateral flow over the time step [m^3] */ - double DLL_EXPORT __STDCALL getSumLateralWaterFlow(long n) + double DLL_EXPORT __STDCALL getSumLateralWaterFlow(long nodeIndex) { if (nodeListPtr == nullptr) return MEMORY_ERROR; - if ((n < 0) || (n >= myStructure.nrNodes)) return INDEX_ERROR; + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) return INDEX_ERROR; double sumLateralFlow = 0.0; for (short i = 0; i < myStructure.nrLateralLinks; i++) { - if (nodeListPtr[n].lateral[i].index != NOLINK) - sumLateralFlow += nodeListPtr[n].lateral[i].sumFlow; + if (nodeListPtr[nodeIndex].lateral[i].index != NOLINK) + sumLateralFlow += nodeListPtr[nodeIndex].lateral[i].sumFlow; } return sumLateralFlow; } @@ -807,19 +852,21 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief getSumLateralWaterFlowIn - * \param n + * \param nodeIndex * \return integrated lateral inflow over the time step [m^3] */ - double DLL_EXPORT __STDCALL getSumLateralWaterFlowIn(long n) + double DLL_EXPORT __STDCALL getSumLateralWaterFlowIn(long nodeIndex) { - if (nodeListPtr == nullptr) return MEMORY_ERROR; - if ((n < 0) || (n >= myStructure.nrNodes)) return INDEX_ERROR; + if (nodeListPtr == nullptr) + return MEMORY_ERROR; + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) + return INDEX_ERROR; double sumLateralFlow = 0.0; for (short i = 0; i < myStructure.nrLateralLinks; i++) - if (nodeListPtr[n].lateral[i].index != NOLINK) - if (nodeListPtr[n].lateral[i].sumFlow > 0) - sumLateralFlow += nodeListPtr[n].lateral[i].sumFlow; + if (nodeListPtr[nodeIndex].lateral[i].index != NOLINK) + if (nodeListPtr[nodeIndex].lateral[i].sumFlow > 0) + sumLateralFlow += nodeListPtr[nodeIndex].lateral[i].sumFlow; return sumLateralFlow; } @@ -827,19 +874,21 @@ int DLL_EXPORT __STDCALL setHydraulicProperties(int waterRetentionCurve, /*! * \brief getSumLateralWaterFlowOut - * \param n + * \param nodeIndex * \return integrated lateral outflow over the time step [m^3] */ - double DLL_EXPORT __STDCALL getSumLateralWaterFlowOut(long n) + double DLL_EXPORT __STDCALL getSumLateralWaterFlowOut(long nodeIndex) { - if (nodeListPtr == nullptr) return MEMORY_ERROR; - if ((n < 0) || (n >= myStructure.nrNodes)) return INDEX_ERROR; + if (nodeListPtr == nullptr) + return MEMORY_ERROR; + if ((nodeIndex < 0) || (nodeIndex >= myStructure.nrNodes)) + return INDEX_ERROR; double sumLateralFlow = 0.0; for (short i = 0; i < myStructure.nrLateralLinks; i++) - if (nodeListPtr[n].lateral[i].index != NOLINK) - if (nodeListPtr[n].lateral[i].sumFlow < 0) - sumLateralFlow += nodeListPtr[n].lateral[i].sumFlow; + if (nodeListPtr[nodeIndex].lateral[i].index != NOLINK) + if (nodeListPtr[nodeIndex].lateral[i].sumFlow < 0) + sumLateralFlow += nodeListPtr[nodeIndex].lateral[i].sumFlow; return sumLateralFlow; } diff --git a/soilFluxes3D/water.cpp b/soilFluxes3D/water.cpp index 4d536f93..15a7890a 100644 --- a/soilFluxes3D/water.cpp +++ b/soilFluxes3D/water.cpp @@ -94,9 +94,8 @@ double runoff(long i, long j, TlinkedNode *link, double deltaT, unsigned long ap */ } - double H = MAXVALUE(Hi, Hj); - double z = MAXVALUE(nodeListPtr[i].z + nodeListPtr[i].Soil->Pond, nodeListPtr[j].z + nodeListPtr[j].Soil->Pond); + double z = MAXVALUE(nodeListPtr[i].z + nodeListPtr[i].pond, nodeListPtr[j].z + nodeListPtr[j].pond); double Hs = H - z; if (Hs <= 0.) return(0.); From a7da74c908cc4ac4405dd997bd6d30fa93828273 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 9 Aug 2024 15:43:08 +0200 Subject: [PATCH 174/179] update --- dbMeteoPoints/dbAggregationsHandler.cpp | 12 ++++++------ pragaProject/pragaProject.cpp | 8 +++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/dbMeteoPoints/dbAggregationsHandler.cpp b/dbMeteoPoints/dbAggregationsHandler.cpp index 731670b4..7321a5df 100644 --- a/dbMeteoPoints/dbAggregationsHandler.cpp +++ b/dbMeteoPoints/dbAggregationsHandler.cpp @@ -122,24 +122,24 @@ bool Crit3DAggregationsDbHandler::writeAggregationZonesTable(QString name, QStri } + bool Crit3DAggregationsDbHandler::writeRasterName(QString rasterName) { QSqlQuery qry(_db); - qry.prepare( "INSERT INTO zones (name)" - " VALUES (:name)" ); - + qry.prepare( "INSERT INTO zones (name) VALUES (:name)" ); qry.bindValue(":name", rasterName); - if( !qry.exec() ) + if(! qry.exec() ) { _error = qry.lastError().text(); return false; } - else - return true; + + return true; } + bool Crit3DAggregationsDbHandler::getRasterName(QString* rasterName) { QSqlQuery qry(_db); diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index 6e846857..b4358908 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -1689,13 +1689,11 @@ bool PragaProject::downloadHourlyDataArkimet(QList variables, QDate sta bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoComputation elab1MeteoComp, QString aggregationString, float threshold, gis::Crit3DRasterGrid* zoneGrid, QDate startDate, QDate endDate, QString periodType, std::vector &outputValues, bool showInfo) { - aggregationMethod spatialElab = getAggregationMethod(aggregationString.toStdString()); std::vector > meteoGridRow(zoneGrid->header->nrRows, std::vector(zoneGrid->header->nrCols, NODATA)); std::vector > meteoGridCol(zoneGrid->header->nrRows, std::vector(zoneGrid->header->nrCols, NODATA)); meteoGridDbHandler->meteoGrid()->saveRowColfromZone(zoneGrid, meteoGridRow, meteoGridCol); - float percValue; bool isMeteoGrid = true; std::string id; @@ -1724,8 +1722,8 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo for (int zoneCol = 0; zoneCol < zoneGrid->header->nrCols; zoneCol++) { float zoneValue = zoneGrid->value[zoneRow][zoneCol]; - double utmx = zoneGrid->utmPoint(zoneRow,zoneCol)->x; - double utmy = zoneGrid->utmPoint(zoneRow,zoneCol)->y; + double utmx = zoneGrid->utmPoint(zoneRow, zoneCol)->x; + double utmy = zoneGrid->utmPoint(zoneRow, zoneCol)->y; if (! isEqual(zoneValue, zoneGrid->header->flag)) { @@ -1813,6 +1811,7 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo if (zoneIndex < 1 || zoneIndex > zoneGrid->maximum) { errorString = "invalid zone index: " + QString::number(zoneIndex); + errorString += "\nZone number has to be between 1 and " + QString::number(zoneGrid->maximum); return false; } @@ -1852,7 +1851,6 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo } case aggrMedian: { - res = sorting::percentile(validValues, size, 50.0, true); break; } From 3a9c9ef1897c0a8e924914571daf9ab4a72359e2 Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 9 Aug 2024 17:23:55 +0200 Subject: [PATCH 175/179] compute aggregation points altitude --- dbMeteoPoints/dbAggregationsHandler.cpp | 57 ++++++++++--------------- dbMeteoPoints/dbAggregationsHandler.h | 26 ++++++++--- gis/gis.cpp | 7 +-- gis/gis.h | 2 +- pragaProject/pragaProject.cpp | 29 +++++++------ project/project.h | 1 + 6 files changed, 65 insertions(+), 57 deletions(-) diff --git a/dbMeteoPoints/dbAggregationsHandler.cpp b/dbMeteoPoints/dbAggregationsHandler.cpp index 7321a5df..e1b08ef8 100644 --- a/dbMeteoPoints/dbAggregationsHandler.cpp +++ b/dbMeteoPoints/dbAggregationsHandler.cpp @@ -35,28 +35,11 @@ Crit3DAggregationsDbHandler::~Crit3DAggregationsDbHandler() } } -QSqlDatabase Crit3DAggregationsDbHandler::db() const -{ - return _db; -} - - -QString Crit3DAggregationsDbHandler::error() const -{ - return _error; -} - -std::map Crit3DAggregationsDbHandler::mapIdMeteoVar() const -{ -return _mapIdMeteoVar; -} - bool Crit3DAggregationsDbHandler::saveAggrData(int nZones, QString aggrType, QString periodType, QDate startDate, QDate endDate, meteoVariable variable, - std::vector< std::vector > aggregatedValues, std::vector lonVector, std::vector latVector) + std::vector< std::vector > aggregatedValues) { initAggregatedTables(nZones, aggrType, periodType, startDate, endDate, variable); - writePointProperties(nZones, aggrType, lonVector, latVector); createTmpAggrTable(); @@ -102,7 +85,6 @@ bool Crit3DAggregationsDbHandler::saveAggrData(int nZones, QString aggrType, QSt bool Crit3DAggregationsDbHandler::writeAggregationZonesTable(QString name, QString filename, QString field) { - QSqlQuery qry(_db); qry.prepare( "INSERT INTO aggregation_zones (name, filename, shape_field)" @@ -117,9 +99,8 @@ bool Crit3DAggregationsDbHandler::writeAggregationZonesTable(QString name, QStri _error = qry.lastError().text(); return false; } - else - return true; + return true; } @@ -166,6 +147,7 @@ bool Crit3DAggregationsDbHandler::getRasterName(QString* rasterName) } } + bool Crit3DAggregationsDbHandler::getAggregationZonesReference(QString name, QString* filename, QString* field) { @@ -195,30 +177,32 @@ bool Crit3DAggregationsDbHandler::getAggregationZonesReference(QString name, QSt } } + void Crit3DAggregationsDbHandler::initAggregatedTables(int numZones, QString aggrType, QString periodType, QDate startDate, QDate endDate, meteoVariable variable) { - int idVariable = getIdfromMeteoVar(variable); for (int i = 1; i <= numZones; i++) { QString statement = QString("CREATE TABLE IF NOT EXISTS `%1_%2_%3` " - "(date_time TEXT, id_variable INTEGER, value REAL, PRIMARY KEY(date_time,id_variable))").arg(i).arg(aggrType).arg(periodType); + "(date_time TEXT, id_variable INTEGER, value REAL, PRIMARY KEY(date_time,id_variable))") + .arg(i).arg(aggrType, periodType); QSqlQuery qry(statement, _db); if( !qry.exec() ) { _error = qry.lastError().text(); } - statement = QString("DELETE FROM `%1_%2_%3` WHERE date_time >= DATE('%4') AND date_time < DATE('%5', '+1 day') AND id_variable = %6") - .arg(i).arg(aggrType).arg(periodType).arg(startDate.toString("yyyy-MM-dd")).arg(endDate.toString("yyyy-MM-dd")).arg(idVariable); + + statement = QString("DELETE FROM `%1_%2_%3` WHERE date_time >= DATE('%4') " + "AND date_time < DATE('%5', '+1 day') AND id_variable = %6") + .arg(i).arg(aggrType, periodType, startDate.toString("yyyy-MM-dd"), endDate.toString("yyyy-MM-dd")).arg(idVariable); qry = QSqlQuery(statement, _db); - if( !qry.exec() ) + if(! qry.exec() ) { _error = qry.lastError().text(); } } - } @@ -234,15 +218,16 @@ bool Crit3DAggregationsDbHandler::existIdPoint(const QString& idPoint) } -bool Crit3DAggregationsDbHandler::writePointProperties(int numZones, QString aggrType, std::vector lonVector, std::vector latVector) +bool Crit3DAggregationsDbHandler::writeAggregationPointProperties(int nrPoints, QString aggrType, + std::vector lonVector, std::vector latVector) { - if ( !_db.tables().contains(QLatin1String("point_properties")) ) + if (! _db.tables().contains(QLatin1String("point_properties")) ) { return false; } QSqlQuery qry(_db); - for (int i = 1; i <= numZones; i++) + for (int i = 1; i <= nrPoints; i++) { QString id = QString::number(i) + "_" + aggrType; QString name = id; @@ -259,7 +244,7 @@ bool Crit3DAggregationsDbHandler::writePointProperties(int numZones, QString agg qry.bindValue(":altitude", 0); qry.bindValue(":is_active", 1); - if( !qry.exec() ) + if(! qry.exec() ) { _error = qry.lastError().text(); return false; @@ -270,6 +255,7 @@ bool Crit3DAggregationsDbHandler::writePointProperties(int numZones, QString agg return true; } + void Crit3DAggregationsDbHandler::createTmpAggrTable() { this->deleteTmpAggrTable(); @@ -389,16 +375,16 @@ int Crit3DAggregationsDbHandler::getIdfromMeteoVar(meteoVariable meteoVar) return key; } + QList Crit3DAggregationsDbHandler::getAggregations() { - QSqlQuery qry(_db); qry.prepare( "SELECT * FROM aggregations"); QString aggregation; QList aggregationList; - if( !qry.exec() ) + if(! qry.exec() ) { _error = qry.lastError().text(); } @@ -410,13 +396,16 @@ QList Crit3DAggregationsDbHandler::getAggregations() aggregationList.append(aggregation); } } + if (aggregationList.isEmpty()) { - _error = "name not found"; + _error = "aggregation table is empty."; } + return aggregationList; } + bool Crit3DAggregationsDbHandler::renameColumn(QString oldColumn, QString newColumn) { QSqlQuery qry(_db); diff --git a/dbMeteoPoints/dbAggregationsHandler.h b/dbMeteoPoints/dbAggregationsHandler.h index e0b15f82..ab0d1986 100644 --- a/dbMeteoPoints/dbAggregationsHandler.h +++ b/dbMeteoPoints/dbAggregationsHandler.h @@ -20,24 +20,33 @@ public: Crit3DAggregationsDbHandler(QString dbname); ~Crit3DAggregationsDbHandler(); - QSqlDatabase db() const; - QString error() const; + + QString error() const { return _error; } + QString name() const { return _db.databaseName(); } + QSqlDatabase db() const { return _db; } + + std::map mapIdMeteoVar() const { return _mapIdMeteoVar; } bool existIdPoint(const QString& idPoint); bool writeAggregationZonesTable(QString name, QString filename, QString field); bool getAggregationZonesReference(QString name, QString* filename, QString* field); void initAggregatedTables(int numZones, QString aggrType, QString periodType, QDate startDate, QDate endDate, meteoVariable variable); - bool writePointProperties(int numZones, QString aggrType, std::vector lonVector, std::vector latVector); - bool saveAggrData(int nZones, QString aggrType, QString periodType, QDate startDate, QDate endDate, meteoVariable variable, std::vector< std::vector > aggregatedValues, std::vector lonVector, std::vector latVector); - void createTmpAggrTable(); - void deleteTmpAggrTable(); + + bool writeAggregationPointProperties(int nrPoints, QString aggrType, std::vector lonVector, std::vector latVector); + + bool saveAggrData(int nZones, QString aggrType, QString periodType, QDate startDate, QDate endDate, + meteoVariable variable, std::vector< std::vector > aggregatedValues); + bool insertTmpAggr(QDate startDate, QDate endDate, meteoVariable variable, std::vector< std::vector > aggregatedValues, int nZones); bool saveTmpAggrData(QString aggrType, QString periodType, int nZones); + std::vector getAggrData(QString aggrType, QString periodType, int zone, QDate startDate, QDate endDate, meteoVariable variable); - std::map mapIdMeteoVar() const; + bool loadVariableProperties(); int getIdfromMeteoVar(meteoVariable meteoVar); + QList getAggregations(); + bool writeRasterName(QString rasterName); bool getRasterName(QString* rasterName); bool renameColumn(QString oldColumn, QString newColumn); @@ -47,6 +56,9 @@ QSqlDatabase _db; std::map _mapIdMeteoVar; QString _error; + + void createTmpAggrTable(); + void deleteTmpAggrTable(); }; #endif // DBAGGREGATIONSHANDLER_H diff --git a/gis/gis.cpp b/gis/gis.cpp index 7bd2265d..d1af69e7 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -1601,10 +1601,11 @@ namespace gis isEqual(first.header->llCorner.y, second.header->llCorner.y)); } + void resampleGrid(const gis::Crit3DRasterGrid& oldGrid, gis::Crit3DRasterGrid* newGrid, - gis::Crit3DRasterHeader* header, aggregationMethod elab, float nodataThreshold) + gis::Crit3DRasterHeader* newHeader, aggregationMethod elab, float nodataRatioThreshold) { - *(newGrid->header) = *header; + *(newGrid->header) = *newHeader; double factor = newGrid->header->cellSize / oldGrid.header->cellSize; int row, col, tmpRow, tmpCol, nrValues, maxValues; @@ -1652,7 +1653,7 @@ namespace gis nrValues = int(values.size()); if (maxValues > 0) { - if ((float(nrValues) / float(maxValues)) > nodataThreshold) + if ((float(nrValues) / float(maxValues)) > nodataRatioThreshold) { if (elab == aggrAverage) value = statistics::mean(values, nrValues); diff --git a/gis/gis.h b/gis/gis.h index 9527dd51..589e27ad 100644 --- a/gis/gis.h +++ b/gis/gis.h @@ -287,7 +287,7 @@ float closestDistanceFromGrid(Crit3DPoint myPoint, const gis::Crit3DRasterGrid& dem); bool compareGrids(const gis::Crit3DRasterGrid& first, const gis::Crit3DRasterGrid& second); void resampleGrid(const gis::Crit3DRasterGrid& oldGrid, gis::Crit3DRasterGrid* newGrid, - Crit3DRasterHeader* header, aggregationMethod elab, float nodataThreshold); + Crit3DRasterHeader* newHeader, aggregationMethod elab, float nodataRatioThreshold); bool temporalYearlyInterpolation(const gis::Crit3DRasterGrid& firstGrid, const gis::Crit3DRasterGrid& secondGrid, int myYear, float minValue, float maxValue, gis::Crit3DRasterGrid* outGrid); } diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index b4358908..60722069 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -1741,13 +1741,21 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo for (unsigned int zonePos = 0; zonePos < zoneVector.size(); zonePos++) { - double lat; - double lon; - utmXvector[zonePos] = utmXvector[zonePos] / count[zonePos]; - utmYvector[zonePos] = utmYvector[zonePos] / count[zonePos]; - gis::getLatLonFromUtm(gisSettings, utmXvector[zonePos], utmYvector[zonePos], &lat, &lon); - latVector.push_back(lat); - lonVector.push_back(lon); + // average x, y + utmXvector[zonePos] = utmXvector[zonePos] / count[zonePos]; + utmYvector[zonePos] = utmYvector[zonePos] / count[zonePos]; + double lat, lon; + gis::getLatLonFromUtm(gisSettings, utmXvector[zonePos], utmYvector[zonePos], &lat, &lon); + latVector.push_back(lat); + lonVector.push_back(lon); + } + + // save point properties + int nrAggregationPoints = int(zoneVector.size()); + if (! aggregationDbHandler->writeAggregationPointProperties(nrAggregationPoints, aggregationString, lonVector, latVector)) + { + errorString = aggregationDbHandler->error(); + return false; } int infoStep = 0; @@ -1765,10 +1773,8 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo for (int col = 0; col < meteoGridDbHandler->gridStructure().header().nrCols; col++) { - if (meteoGridDbHandler->meteoGrid()->getMeteoPointActiveId(row, col, &id)) { - Crit3DMeteoPoint* meteoPoint = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row, col); // copy data to MPTemp @@ -1803,7 +1809,6 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo { for (int zoneCol = 0; zoneCol < zoneGrid->header->nrCols; zoneCol++) { - float zoneValue = zoneGrid->value[zoneRow][zoneCol]; if (! isEqual(zoneValue, zoneGrid->header->flag)) { @@ -1879,12 +1884,12 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo { zoneVector[zonePos].clear(); } - } // save dailyElabAggregation result into DB if (showInfo) setProgressBar("Save data...", 0); - if (! aggregationDbHandler->saveAggrData(int(zoneGrid->maximum), aggregationString, periodType, startDate, endDate, variable, dailyElabAggregation, lonVector, latVector)) + if (! aggregationDbHandler->saveAggrData(int(zoneGrid->maximum), aggregationString, periodType, + startDate, endDate, variable, dailyElabAggregation)) { errorString = aggregationDbHandler->error(); if (showInfo) closeProgressBar(); diff --git a/project/project.h b/project/project.h index 03f37e3c..1560ef1d 100644 --- a/project/project.h +++ b/project/project.h @@ -241,6 +241,7 @@ bool loadMeteoGridHourlyData(QDateTime firstDate, QDateTime lastDate, bool showInfo); bool loadMeteoGridMonthlyData(QDate firstDate, QDate lastDate, bool showInfo); void loadMeteoGridData(QDate firstDate, QDate lastDate, bool showInfo); + QDateTime findDbPointLastTime(); QDateTime findDbPointFirstTime(); From c61d11e7c6adb1b3480be79fbc0b15dedf8ada9c Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 9 Aug 2024 19:30:48 +0200 Subject: [PATCH 176/179] compute aggregation points altitude --- climate/climate.cpp | 2 +- gis/gis.cpp | 56 ++++++---- homogeneityWidget/homogeneityWidget.cpp | 12 +-- interpolation/interpolation.cpp | 7 +- mathFunctions/statistics.cpp | 50 ++++----- mathFunctions/statistics.h | 4 +- .../pointStatisticsWidget.cpp | 4 +- pragaProject/pragaProject.cpp | 4 +- project/project.cpp | 100 +++++++++++++++++- project/project.h | 5 +- 10 files changed, 180 insertions(+), 64 deletions(-) diff --git a/climate/climate.cpp b/climate/climate.cpp index 5b179518..5ac40436 100644 --- a/climate/climate.cpp +++ b/climate/climate.cpp @@ -1101,7 +1101,7 @@ float thomDailyMean(TObsDataH* hourlyValues, float minimumPercentage) if ( (float(nData) / 24 * 100) < minimumPercentage) thomDailyMean = NODATA; else - thomDailyMean = statistics::mean(thomValues, nData); + thomDailyMean = statistics::mean(thomValues); return thomDailyMean; diff --git a/gis/gis.cpp b/gis/gis.cpp index d1af69e7..b4754afb 100644 --- a/gis/gis.cpp +++ b/gis/gis.cpp @@ -1607,12 +1607,11 @@ namespace gis { *(newGrid->header) = *newHeader; - double factor = newGrid->header->cellSize / oldGrid.header->cellSize; + double resampleFactor = newGrid->header->cellSize / oldGrid.header->cellSize; + int row, col, tmpRow, tmpCol, nrValues, maxValues; - float value, tmpValue; - double x, y; gis::Crit3DPoint myLL, myUR; - std::vector values; + std::vector values; newGrid->initializeGrid(); @@ -1621,42 +1620,56 @@ namespace gis { newGrid->value[row][col] = newGrid->header->flag; - value = NODATA; - - if (factor < 1 || elab == aggrCenter) + float value = NODATA; + if (resampleFactor < 1. || elab == aggrCenter) { + double x, y; newGrid->getXY(row, col, x, y); oldGrid.getRowCol(x, y, tmpRow, tmpCol); if (! gis::isOutOfGridRowCol(tmpRow, tmpCol, oldGrid)) + { value = oldGrid.value[tmpRow][tmpCol]; + } } else { - newGrid->getXY(row, col, x, y); - myLL.utm.x = x - (newGrid->header->cellSize / 2); - myLL.utm.y = y - (newGrid->header->cellSize / 2); - myUR.utm.x = x + (newGrid->header->cellSize / 2); - myUR.utm.y = y + (newGrid->header->cellSize / 2); + double x0, y0; + newGrid->getXY(row, col, x0, y0); + myLL.utm.x = x0 - (newGrid->header->cellSize / 2); + myLL.utm.y = y0 - (newGrid->header->cellSize / 2); + myUR.utm.x = x0 + (newGrid->header->cellSize / 2); + myUR.utm.y = y0 + (newGrid->header->cellSize / 2); + + double step = oldGrid.header->cellSize * 0.5; values.clear(); maxValues = 0; - double step = oldGrid.header->cellSize * 0.5; - for (x = myLL.utm.x; x <= myUR.utm.x; x += step) - for (y = myLL.utm.y; y <= myUR.utm.y; y += step) + + double x = myLL.utm.x; + while(x <= myUR.utm.x) + { + double y = myLL.utm.y; + while(y <= myUR.utm.y) { maxValues++; - tmpValue = gis::getValueFromXY(oldGrid, x, y); + float tmpValue = gis::getValueFromXY(oldGrid, x, y); if (! isEqual(tmpValue, oldGrid.header->flag)) + { values.push_back(tmpValue); - } + } + y += step; + } + x += step; + } nrValues = int(values.size()); + if (maxValues > 0) { if ((float(nrValues) / float(maxValues)) > nodataRatioThreshold) { if (elab == aggrAverage) - value = statistics::mean(values, nrValues); + value = statistics::mean(values); else if (elab == aggrMedian) value = sorting::percentile(values, nrValues, 50, true); else if (elab == aggrPrevailing) @@ -1665,14 +1678,17 @@ namespace gis } } - if (! isEqual(value, NODATA)) newGrid->value[row][col] = value; + if (! isEqual(value, NODATA)) + { + newGrid->value[row][col] = value; + } } gis::updateMinMaxRasterGrid(newGrid); newGrid->isLoaded = true; - } + bool temporalYearlyInterpolation(const gis::Crit3DRasterGrid& firstGrid, const gis::Crit3DRasterGrid& secondGrid, int myYear, float minValue, float maxValue, gis::Crit3DRasterGrid* outGrid) { diff --git a/homogeneityWidget/homogeneityWidget.cpp b/homogeneityWidget/homogeneityWidget.cpp index 690b20b6..1a56cc68 100644 --- a/homogeneityWidget/homogeneityWidget.cpp +++ b/homogeneityWidget/homogeneityWidget.cpp @@ -1060,7 +1060,7 @@ void Crit3DHomogeneityWidget::executeClicked() myValidValues.push_back((double)myAnnualSeries[i]); } } - double myAverage = statistics::mean(myValidValues, int(myValidValues.size())); + double myAverage = statistics::mean(myValidValues); std::vector myRefAverage; std::vector r2; std::vector> refSeriesVector; @@ -1079,7 +1079,7 @@ void Crit3DHomogeneityWidget::executeClicked() myRefValidValues.push_back((double)refSeries[i]); } } - myRefAverage.push_back(statistics::mean(myRefValidValues, int(myRefValidValues.size()))); + myRefAverage.push_back(statistics::mean(myRefValidValues)); statistics::linearRegression(myAnnualSeries, refSeries, long(myAnnualSeries.size()), false, &y_intercept, &trend, &r2Value); r2.push_back(r2Value); } @@ -1148,7 +1148,7 @@ void Crit3DHomogeneityWidget::executeClicked() myValidValues.push_back(myQ[i]); } } - double myQAverage = statistics::mean(myValidValues, int(myValidValues.size())); + double myQAverage = statistics::mean(myValidValues); double myQDevStd = statistics::standardDeviation(myValidValues, int(myValidValues.size())); std::vector myZ; for (int i = 0; i z1; @@ -1205,7 +1205,7 @@ void Crit3DHomogeneityWidget::executeClicked() myValidValues.push_back(z1[i]); } } - double myZ1Average = statistics::mean(myValidValues, int(myValidValues.size())); + double myZ1Average = statistics::mean(myValidValues); myValidValues.clear(); for (int i = 0; i &interpolationPoints, Crit3DInterpolationSettings* mySettings, - Crit3DMeteoSettings* meteoSettings, - const Crit3DTime &myTime) + Crit3DMeteoSettings* meteoSettings) { float avgError; @@ -2302,7 +2301,7 @@ void optimalDetrending(meteoVariable myVar, Crit3DMeteoPoint* &myMeteoPoints, in mySettings->setCurrentCombination(myCombination); if (mySettings->getUseTD() && getUseTdVar(myVar)) - topographicDistanceOptimize(myVar, myMeteoPoints, nrMeteoPoints, interpolationPoints, mySettings, meteoSettings, myTime); + topographicDistanceOptimize(myVar, myMeteoPoints, nrMeteoPoints, interpolationPoints, mySettings, meteoSettings); if (computeResiduals(myVar, myMeteoPoints, nrMeteoPoints, interpolationPoints, mySettings, meteoSettings, true, true)) { @@ -2371,7 +2370,7 @@ bool preInterpolation(std::vector &myPoints, Crit if (mySettings->getUseTD() && getUseTdVar(myVar)) { - topographicDistanceOptimize(myVar, myMeteoPoints, nrMeteoPoints, myPoints, mySettings, meteoSettings, myTime); + topographicDistanceOptimize(myVar, myMeteoPoints, nrMeteoPoints, myPoints, mySettings, meteoSettings); } return true; diff --git a/mathFunctions/statistics.cpp b/mathFunctions/statistics.cpp index 51b99143..2ee6f098 100644 --- a/mathFunctions/statistics.cpp +++ b/mathFunctions/statistics.cpp @@ -42,7 +42,7 @@ float statisticalElab(meteoComputation elab, float param, std::vector val switch(elab) { case average: - return statistics::mean(values, nValues); + return statistics::mean(values); case maxInList: return statistics::maxList(values, nValues); case minInList: @@ -246,7 +246,7 @@ namespace statistics { if (measured.size() != simulated.size()) return NODATA; - float obsAvg = mean(measured, int(measured.size())); + float obsAvg = mean(measured); if (isEqual(obsAvg, NODATA)) return NODATA; @@ -1102,7 +1102,7 @@ namespace statistics if (nrList <= 1) return NODATA; - myMean = mean(myList,nrList); + myMean = mean(myList); squareDiff = 0; nrValidValues = 0; @@ -1129,7 +1129,7 @@ namespace statistics if (nrList <= 1) return NODATA; - myMean = mean(myList,nrList); + myMean = mean(myList); squareDiff = 0; nrValidValues = 0; @@ -1199,52 +1199,54 @@ namespace statistics return NODATA; } - float mean(std::vector myList, int nrList) + + float mean(std::vector list) { - float sum=0.; - int i, nrValidValues; + if (list.size() < 1) + return NODATA; - if (nrList < 1) return NODATA; - nrValidValues = 0; + int nrValidValues = 0; + double sum = 0.; - for (i = 0; i < nrList; i++) + for (int i = 0; i < list.size(); i++) { - if (myList[i]!= NODATA) + if (! isEqual(list[i], NODATA)) { - sum += myList[i]; + sum += double(list[i]); nrValidValues++; } } - if (nrValidValues > 0) - return (sum/(float)(nrValidValues)); - else + if (nrValidValues == 0) return NODATA; + + return float(sum / double(nrValidValues)); } - double mean(std::vector myList, int nrList) + + double mean(std::vector list) { - double sum=0.; - int i, nrValidValues; + if (list.size() < 1) return NODATA; - if (nrList < 1) return NODATA; - nrValidValues = 0; + int nrValidValues = 0; + double sum=0; - for (i = 0; i < nrList; i++) + for (int i = 0; i < int(list.size()); i++) { - if (myList[i]!= NODATA) + if (list[i] != NODATA) { - sum += myList[i]; + sum += list[i]; nrValidValues++; } } if (nrValidValues > 0) - return (sum/(double)(nrValidValues)); + return (sum / (double)(nrValidValues)); else return NODATA; } + double mean(double *myList, int nrList) { double sum=0.; diff --git a/mathFunctions/statistics.h b/mathFunctions/statistics.h index 530a9d93..fcc6f102 100644 --- a/mathFunctions/statistics.h +++ b/mathFunctions/statistics.h @@ -48,8 +48,8 @@ double variance(std::vector myList, int nrList); double variance(double *myList, int nrList); float mean(float *myList, int nrList); - float mean(std::vector myList, int nrList); - double mean(std::vector myList, int nrList); + float mean(std::vector list); + double mean(std::vector list); double mean(double *myList, int nrList); float covariance(float *myList1, int nrList1,float *myList2, int nrList2); double covariance(double *myList1, int nrList1,double *myList2, int nrList2); diff --git a/pointStatisticsWidget/pointStatisticsWidget.cpp b/pointStatisticsWidget/pointStatisticsWidget.cpp index 2e7f70ae..672bf8ae 100644 --- a/pointStatisticsWidget/pointStatisticsWidget.cpp +++ b/pointStatisticsWidget/pointStatisticsWidget.cpp @@ -1171,7 +1171,7 @@ void Crit3DPointStatisticsWidget::plot() visualizedNrValues = visualizedNrValues + 1; } } - avg = statistics::mean(series, nrValues); + avg = statistics::mean(series); dev_std = statistics::standardDeviation(series, nrValues); millile3dev = sorting::percentile(sortedSeries, nrValues, 99.73f, true); millile_3Dev = sorting::percentile(sortedSeries, nrValues, 0.27f, false); @@ -1449,7 +1449,7 @@ void Crit3DPointStatisticsWidget::plot() } } } - avg = statistics::mean(series, nrValues); + avg = statistics::mean(series); dev_std = statistics::standardDeviation(series, nrValues); millile3dev = sorting::percentile(sortedSeries, nrValues, 99.73f, true); millile_3Dev = sorting::percentile(sortedSeries, nrValues, 0.27f, false); diff --git a/pragaProject/pragaProject.cpp b/pragaProject/pragaProject.cpp index 60722069..a50730ba 100644 --- a/pragaProject/pragaProject.cpp +++ b/pragaProject/pragaProject.cpp @@ -1851,7 +1851,7 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo { case aggrAverage: { - res = statistics::mean(validValues, size); + res = statistics::mean(validValues); break; } case aggrMedian: @@ -1872,7 +1872,7 @@ bool PragaProject::averageSeriesOnZonesMeteoGrid(meteoVariable variable, meteoCo default: { // default: average - res = statistics::mean(validValues, size); + res = statistics::mean(validValues); break; } } diff --git a/project/project.cpp b/project/project.cpp index dadd9e02..cb857907 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -1188,6 +1188,7 @@ bool Project::loadMeteoPointsDB(QString fileName) { logError("Error reading proxy values"); } + closeLogInfo(); // position with respect to DEM if (DEM.isLoaded) @@ -2206,7 +2207,7 @@ bool Project::interpolationOutputPoints(std::vector initialize(); @@ -2295,7 +2296,7 @@ bool Project::interpolationCv(meteoVariable myVar, const Crit3DTime& myTime, cro if (! computeResiduals(myVar, meteoPoints, nrMeteoPoints, interpolationPoints, &interpolationSettings, meteoSettings, true, true)) return false; - if (! computeStatisticsCrossValidation(myTime, myVar, myStats)) + if (! computeStatisticsCrossValidation(myStats)) return false; return true; @@ -4886,3 +4887,98 @@ bool Project::waterTableAssignMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDat return false; } } + + + +bool Project::assignAltitudeToAggregationPoints() +{ + if (! DEM.isLoaded) + { + errorString = ERROR_STR_MISSING_DEM; + return false; + } + + if (aggregationDbHandler == nullptr) + { + errorString = "Open or create a new aggregation database before."; + return false; + } + + if (meteoPointsLoaded) + { + errorString = "Close Meteo Points db before execute this operation!"; + return false; + } + + // check aggregation raster + QString rasterName; + if (! aggregationDbHandler->getRasterName(&rasterName)) + { + errorString = "Missing raster name inside aggregation db."; + return false; + } + + QString rasterFileName = aggregationPath + "/" + rasterName; + QFileInfo rasterFileFltInfo(rasterFileName + ".flt"); + QFileInfo rasterFileHdrInfo(rasterFileName + ".hdr"); + if (! rasterFileFltInfo.exists() || ! rasterFileHdrInfo.exists()) + { + errorString = "Raster file does not exist: " + rasterFileName; + return false; + } + + // load aggregation db as meteo points db + if (! loadMeteoPointsDB(aggregationDbHandler->name()) ) + { + errorString = "Error in load aggregation points: " + errorString; + return false; + } + + // load aggregation raster + std::string errorStr = ""; + std::string fileNameStdStr = rasterFileName.toStdString() + ".flt"; + gis::Crit3DRasterGrid *aggregationRaster; + aggregationRaster = new(gis::Crit3DRasterGrid); + if (! gis::openRaster(fileNameStdStr, aggregationRaster, gisSettings.utmZone, errorStr)) + { + errorString = "Open raster failed: " + QString::fromStdString(errorStr); + return false; + } + + // resample aggregation DEM + gis::Crit3DRasterGrid *aggregationDEM; + aggregationDEM = new(gis::Crit3DRasterGrid); + gis::resampleGrid(DEM, aggregationDEM, aggregationRaster->header, aggrAverage, 0.1f); + + // compute average altitude from aggregation DEM + for (int i = 0; i < nrMeteoPoints; i++) + { + QString idStr = QString::fromStdString(meteoPoints[i].id); + QList idList = idStr.split('_'); + float zoneNr = idList[0].toFloat(); + + std::vector values; + for (int row = 0; row < aggregationRaster->header->nrRows; row++) + { + for (int col = 0; col < aggregationRaster->header->nrCols; col++) + { + if (isEqual(aggregationRaster->value[row][col], zoneNr)) + { + float z = aggregationDEM->value[row][col]; + if (! isEqual(z, aggregationDEM->header->flag)) + { + values.push_back(z); + } + } + } + } + + // update point properties + float altitude = statistics::mean(values); + QString query = QString("UPDATE point_properties SET altitude = %1 WHERE id_point = '%2'").arg(altitude).arg(idStr); + aggregationDbHandler->db().exec(query); + } + + closeMeteoPointsDB(); + return true; +} diff --git a/project/project.h b/project/project.h index 1560ef1d..30f833b9 100644 --- a/project/project.h +++ b/project/project.h @@ -268,7 +268,8 @@ bool interpolationOutputPoints(std::vector &interpolationPoints, gis::Crit3DRasterGrid *outputGrid, meteoVariable myVar); bool interpolationCv(meteoVariable myVar, const Crit3DTime& myTime, crossValidationStatistics* myStats); - bool computeStatisticsCrossValidation(Crit3DTime myTime, meteoVariable myVar, crossValidationStatistics *myStats); + + bool computeStatisticsCrossValidation(crossValidationStatistics *myStats); bool meteoGridAggregateProxy(std::vector &myGrids); frequencyType getCurrentFrequency() const; @@ -313,6 +314,8 @@ bool waterTableAssignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint); bool waterTableAssignMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate); + bool assignAltitudeToAggregationPoints(); + private slots: void deleteMeteoWidgetPoint(int id); void deleteMeteoWidgetGrid(int id); From dd0a2616fc29ad1842649d5f083d23f4129909db Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 9 Aug 2024 19:48:24 +0200 Subject: [PATCH 177/179] update --- project/project.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/project/project.cpp b/project/project.cpp index cb857907..2df0a0a0 100644 --- a/project/project.cpp +++ b/project/project.cpp @@ -4889,7 +4889,6 @@ bool Project::waterTableAssignMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDat } - bool Project::assignAltitudeToAggregationPoints() { if (! DEM.isLoaded) @@ -4950,6 +4949,8 @@ bool Project::assignAltitudeToAggregationPoints() aggregationDEM = new(gis::Crit3DRasterGrid); gis::resampleGrid(DEM, aggregationDEM, aggregationRaster->header, aggrAverage, 0.1f); + setProgressBar("Compute altitude..", nrMeteoPoints); + // compute average altitude from aggregation DEM for (int i = 0; i < nrMeteoPoints; i++) { @@ -4977,8 +4978,11 @@ bool Project::assignAltitudeToAggregationPoints() float altitude = statistics::mean(values); QString query = QString("UPDATE point_properties SET altitude = %1 WHERE id_point = '%2'").arg(altitude).arg(idStr); aggregationDbHandler->db().exec(query); + + updateProgressBar(i); } closeMeteoPointsDB(); return true; } + From 350a7fa952e882fd4c73f2cd8e45d6ff1a96d37d Mon Sep 17 00:00:00 2001 From: ftomei Date: Fri, 9 Aug 2024 20:08:02 +0200 Subject: [PATCH 178/179] update --- criteriaModel/criteria1DCase.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/criteriaModel/criteria1DCase.cpp b/criteriaModel/criteria1DCase.cpp index b2cdd326..f3e2f949 100644 --- a/criteriaModel/criteria1DCase.cpp +++ b/criteriaModel/criteria1DCase.cpp @@ -182,7 +182,7 @@ bool Crit1DCase::initializeNumericalFluxes(std::string &error) double maxSurfaceWater = crop.getSurfaceWaterPonding() * 0.001; // [m] double roughnessManning = 0.024; // [s m^-0.33] int surfaceIndex = 0; - soilFluxes3D::setSurfaceProperties(surfaceIndex, roughnessManning, maxSurfaceWater); + soilFluxes3D::setSurfaceProperties(surfaceIndex, roughnessManning); // center float x0 = 0; @@ -194,6 +194,7 @@ bool Crit1DCase::initializeNumericalFluxes(std::string &error) int nodeIndex = 0; soilFluxes3D::setNode(nodeIndex, x0, y0, z0, area, isSurface, true, BOUNDARY_RUNOFF, float(unit.slope), float(ly)); soilFluxes3D::setNodeSurface(nodeIndex, surfaceIndex); + soilFluxes3D::setNodePond(nodeIndex, maxSurfaceWater); soilFluxes3D::setNodeLink(nodeIndex, nodeIndex + 1, DOWN, float(area)); // set soil nodes From 72a26ed3385640e31b7a5582fe2d156d3e025c2f Mon Sep 17 00:00:00 2001 From: ftomei Date: Mon, 12 Aug 2024 15:59:34 +0200 Subject: [PATCH 179/179] update --- gdal.pri | 25 ++++++++----------------- gdalHandler/gdalHandler.pro | 2 -- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/gdal.pri b/gdal.pri index 1d059af3..c7703404 100644 --- a/gdal.pri +++ b/gdal.pri @@ -4,19 +4,12 @@ # How to compile on windows: # # win32-msvc (Microsoft Visual C) -# - install GDAL (32 or 64 bit) from OSGeo4W https://trac.osgeo.org/osgeo4w/ -# - add GDAL_PATH to the system variables - example: GDAL_PATH = C:\OSGeo4W64 -# - add GDAL_DATA to the system variables - example: GDAL_DATA = C:\OSGeo4W64\share\epsg_csv -# - add PROJ_LIB to the system variables - example: PROJ_LIB = C:\OSGeo4W64\share\proj +# - install GDAL from OSGeo4W https://trac.osgeo.org/osgeo4w/ +# - add GDAL_PATH to the system variables - example: GDAL_PATH = C:\OSGeo4W +# - add GDAL_DATA to the system variables - example: GDAL_DATA = C:\OSGeo4W\share\epsg_csv +# - add PROJ_LIB to the system variables - example: PROJ_LIB = C:\OSGeo4W\share\proj # - add OSGeo4W\bin to the system path # -# win32-g++ (MinGW) -# Unfortunately it doesn't seem to work at the moment -# - install and update MSYS2 from https://www.msys2.org/ -# - run MSYS2 shell and install GDAL package - example: pacman -S mingw-w64-x86_64-gdal -# - add MSYS_PATH to system variables - example: MSYS_PATH = C:\msys64\mingw64 -# - add msys\mingw\bin to the system path -# #------------------------------------------------------------------------------------------ unix:!macx { @@ -28,21 +21,19 @@ unix:!macx { } win32-msvc { - LIBS += -L$$(GDAL_PATH)/lib/ -lgdal_i -lgeos_c + LIBS += -L$$(GDAL_PATH)/lib/ -lgdal_i INCLUDEPATH += $$(GDAL_PATH)/include DEPENDPATH += $$(GDAL_PATH)/include } win32-g++ { - LIBS += -L$$(MSYS_PATH)/lib/ -lgdal -lgeos -lgeos_c + LIBS += -L$$(GDAL_PATH)/lib/ -lgdal - INCLUDEPATH += $$(MSYS_PATH)/include - DEPENDPATH += $$(MSYS_PATH)/include + INCLUDEPATH += $$(GDAL_PATH)/include + DEPENDPATH += $$(GDAL_PATH)/include PRE_TARGETDEPS += $$(MSYS_PATH)/lib/libgdal.a - PRE_TARGETDEPS += $$(MSYS_PATH)/lib/libgeos.dll.a - PRE_TARGETDEPS += $$(MSYS_PATH)/lib/libgeos_c.dll.a } mac { diff --git a/gdalHandler/gdalHandler.pro b/gdalHandler/gdalHandler.pro index 8e9c39a2..a823f52b 100644 --- a/gdalHandler/gdalHandler.pro +++ b/gdalHandler/gdalHandler.pro @@ -34,13 +34,11 @@ SOURCES += \ gdalExtensions.cpp \ gdalRasterFunctions.cpp \ gdalShapeFunctions.cpp \ -# gdalShapeIntersection.cpp HEADERS += \ gdalExtensions.h \ gdalRasterFunctions.h \ gdalShapeFunctions.h \ -# gdalShapeIntersection.h include(../gdal.pri)