Skip to content

Commit

Permalink
Fix LOCF in generateMissingWeather()
Browse files Browse the repository at this point in the history
- close #437 "Incorrect count of LOCF in generateMissingWeather()"

- the number of days on which LOCF was applied is now correctly counting only the days when there was a missing value that was replaced by a non-missing value
- previously, any day with a missing value was counted -- even if it was not replaced by a non-missing value

- for instance, inputs without solar radiation or without vapor pressure previously caused that every day was counted towards the maximum permissible number of LOCFs

- note: initial values for LOCF changed from 0 to "missing" -- this matters only for days at the beginning of the time period that have missing values before a later day with a first non-missing value
  • Loading branch information
dschlaep committed Nov 25, 2024
1 parent 74e7b8c commit 018dbac
Showing 1 changed file with 59 additions and 26 deletions.
85 changes: 59 additions & 26 deletions src/SW_Weather.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@
#include <stdlib.h> // for atoi, free
#include <string.h> // for memset, NULL, strcpy


/* Weather generation methods */
/** Markov weather generator method, see generateMissingWeather() */
const static unsigned int wgMKV = 2;

/** Weather generation method LOCF, see generateMissingWeather() */
const static unsigned int wgLOCF = 1;


/* =================================================== */
/* Local Function Definitions */
/* --------------------------------------------------- */
Expand Down Expand Up @@ -1037,12 +1046,20 @@ void generateMissingWeather(
LOG_INFO *LogInfo
) {

int year;
unsigned int yearIndex, numDaysYear, day, iMissing;

double yesterdayPPT = 0., yesterdayTempMin = 0., yesterdayTempMax = 0.,
yesterdayCloudCov = 0., yesterdayWindSpeed = 0.,
yesterdayRelHum = 0., yesterdayShortWR = 0., yesterdayActVP = 0.;
unsigned int year;
unsigned int yearIndex;
unsigned int numDaysYear;
unsigned int day;
unsigned int nFilledLOCF;

double yesterdayPPT = SW_MISSING;
double yesterdayTempMin = SW_MISSING;
double yesterdayTempMax = SW_MISSING;
double yesterdayCloudCov = SW_MISSING;
double yesterdayWindSpeed = SW_MISSING;
double yesterdayRelHum = SW_MISSING;
double yesterdayShortWR = SW_MISSING;
double yesterdayActVP = SW_MISSING;

Bool any_missing;
Bool missing_Tmax = swFALSE, missing_Tmin = swFALSE, missing_PPT = swFALSE,
Expand Down Expand Up @@ -1073,15 +1090,16 @@ void generateMissingWeather(
for (yearIndex = 0; yearIndex < n_years; yearIndex++) {
year = yearIndex + startYear;
numDaysYear = Time_get_lastdoy_y(year);
iMissing = 0;
nFilledLOCF = 0;

for (day = 0; day < numDaysYear; day++) {
/* Determine variables with missing values */

missing_Tmax = (Bool) missing(allHist[yearIndex]->temp_max[day]);
missing_Tmin = (Bool) missing(allHist[yearIndex]->temp_min[day]);
missing_PPT = (Bool) missing(allHist[yearIndex]->ppt[day]);

if (method != 2) {
// `SW_MKV_today()` currently generates only Tmax, Tmin, and PPT
if (method == wgLOCF) {
missing_CloudCov =
(Bool) missing(allHist[yearIndex]->cloudcov_daily[day]);
missing_WindSpeed =
Expand All @@ -1102,8 +1120,8 @@ void generateMissingWeather(
if (any_missing) {
// some of today's values are missing

if (method == 2) {
// Weather generator
if (method == wgMKV) {
// Markov weather generator (Tmax, Tmin, and PPT)
allHist[yearIndex]->ppt[day] = yesterdayPPT;
SW_MKV_today(
SW_Markov,
Expand All @@ -1118,7 +1136,7 @@ void generateMissingWeather(
return; // Exit function prematurely due to error
}

} else if (method == 1) {
} else if (method == wgLOCF) {
// LOCF (temp, cloud cover, wind speed, relative humidity,
// shortwave radiation, and actual vapor pressure) + 0 (PPT)
allHist[yearIndex]->temp_max[day] =
Expand Down Expand Up @@ -1157,11 +1175,23 @@ void generateMissingWeather(
missing_PPT ? 0. : allHist[yearIndex]->ppt[day];


// Throw an error if too many values per calendar year are
// missing
iMissing++;
// Throw an error if too many missing values have
// been replaced with non-missing values by the LOCF method
// per calendar year
if (
(missing_Tmax && !missing(yesterdayTempMax)) ||
(missing_Tmin && !missing(yesterdayTempMin)) ||
(missing_PPT && !missing(allHist[yearIndex]->ppt[day])) ||
(missing_CloudCov && !missing(yesterdayCloudCov)) ||
(missing_WindSpeed && !missing(yesterdayWindSpeed)) ||
(missing_RelHum && !missing(yesterdayRelHum)) ||
(missing_ShortWR && !missing(yesterdayShortWR)) ||
(missing_ActVP && !missing(yesterdayActVP))

Check warning on line 1189 in src/SW_Weather.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Weather.c#L1189

Added line #L1189 was not covered by tests
) {
nFilledLOCF++;
}

if (iMissing > optLOCF_nMax) {
if (nFilledLOCF > optLOCF_nMax) {
LogError(
LogInfo,
LOGERROR,
Expand All @@ -1184,13 +1214,16 @@ void generateMissingWeather(
}

yesterdayPPT = allHist[yearIndex]->ppt[day];
yesterdayTempMax = allHist[yearIndex]->temp_max[day];
yesterdayTempMin = allHist[yearIndex]->temp_min[day];
yesterdayCloudCov = allHist[yearIndex]->cloudcov_daily[day];
yesterdayWindSpeed = allHist[yearIndex]->windspeed_daily[day];
yesterdayRelHum = allHist[yearIndex]->r_humidity_daily[day];
yesterdayShortWR = allHist[yearIndex]->shortWaveRad[day];
yesterdayActVP = allHist[yearIndex]->actualVaporPressure[day];

if (method == wgLOCF) {
yesterdayTempMax = allHist[yearIndex]->temp_max[day];
yesterdayTempMin = allHist[yearIndex]->temp_min[day];
yesterdayCloudCov = allHist[yearIndex]->cloudcov_daily[day];
yesterdayWindSpeed = allHist[yearIndex]->windspeed_daily[day];
yesterdayRelHum = allHist[yearIndex]->r_humidity_daily[day];
yesterdayShortWR = allHist[yearIndex]->shortWaveRad[day];
yesterdayActVP = allHist[yearIndex]->actualVaporPressure[day];
}
}
}
}
Expand Down Expand Up @@ -1750,18 +1783,18 @@ void SW_WTH_setup(

case 1:
// weather generator
SW_Weather->generateWeatherMethod = 2;
SW_Weather->generateWeatherMethod = wgMKV;

Check warning on line 1786 in src/SW_Weather.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Weather.c#L1786

Added line #L1786 was not covered by tests
break;

case 2:
// weather generatory only
SW_Weather->generateWeatherMethod = 2;
SW_Weather->generateWeatherMethod = wgMKV;

Check warning on line 1791 in src/SW_Weather.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Weather.c#L1791

Added line #L1791 was not covered by tests
SW_Weather->use_weathergenerator_only = swTRUE;
break;

case 3:
// LOCF (temp) + 0 (PPT)
SW_Weather->generateWeatherMethod = 1;
SW_Weather->generateWeatherMethod = wgLOCF;

Check warning on line 1797 in src/SW_Weather.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Weather.c#L1797

Added line #L1797 was not covered by tests
break;

default:
Expand Down

0 comments on commit 018dbac

Please sign in to comment.