From 274d2f1ce196ab9ac03cdc1b39e3c83f8ebd01a3 Mon Sep 17 00:00:00 2001 From: Chip Gobs Date: Fri, 12 Dec 2014 13:12:48 -0500 Subject: [PATCH] VLab Issue #5615 MPE:Null DAA Radar Product Handling; fixes #5615 Former-commit-id: 0ce3a04b6ba70618339cb3c88e2cb241b84471cb [formerly 34006d87caca7ba9486a4d8f6041904221fead2f] [formerly 5c76a59cc16435f2e2d82ba7941b865eee674be1] [formerly 0ce3a04b6ba70618339cb3c88e2cb241b84471cb [formerly 34006d87caca7ba9486a4d8f6041904221fead2f] [formerly 5c76a59cc16435f2e2d82ba7941b865eee674be1] [formerly d6619ab0e0b678389c45373aea068d8588d148fa [formerly 5c76a59cc16435f2e2d82ba7941b865eee674be1 [formerly ef877ed41166503b844c81ac7e3108421ff872ec]]]] Former-commit-id: d6619ab0e0b678389c45373aea068d8588d148fa Former-commit-id: 65ebbd66b6de78da3085c4403d3dfff759919358 [formerly 2f24c94bc1974c42f90e320c43482c333d7b2599] [formerly c9fdea8b3568581e2fed37e7e83cfaef5d6feb60 [formerly e94adef7b095918243c68035cec81392d6b527f9]] Former-commit-id: f431afdfcdad9bc5c25c5b34f0262a68eb207cd1 [formerly 66ae7f381901546db91b83703ce686cebccb51a1] Former-commit-id: 258b6f2ed62e7f499aea8050b186e3b84a2149cf --- nativeLib/rary.ohd.pproc/inc/mpe_fieldgen.h | 3 +- .../src/MPEFieldGen/TEXT/readRDMosaicRadars.c | 735 +++++++++++++----- 2 files changed, 563 insertions(+), 175 deletions(-) diff --git a/nativeLib/rary.ohd.pproc/inc/mpe_fieldgen.h b/nativeLib/rary.ohd.pproc/inc/mpe_fieldgen.h index 9adc7da70b..3e34592f6b 100644 --- a/nativeLib/rary.ohd.pproc/inc/mpe_fieldgen.h +++ b/nativeLib/rary.ohd.pproc/inc/mpe_fieldgen.h @@ -12,7 +12,7 @@ * DATE PROGRAMMER DESCRIPTION/REASON * 9/15/2006 P Tilles added lid to structure gage_radar_pair_struct * August 2008 P Tilles added arrays for Q2 -* +* 12/12/2014 C Gobs added include "DAARadar.h" ******************************************************************************** */ @@ -37,6 +37,7 @@ #include "get_os_system.h" #include "convert_hrap.h" /* Hrap to LatLon Conversion utilities */ #include "time_convert.h" +#include "DAARadar.h" #include "HourlyPC.h" #include "mpe_write_xmrg.h" diff --git a/nativeLib/rary.ohd.pproc/src/MPEFieldGen/TEXT/readRDMosaicRadars.c b/nativeLib/rary.ohd.pproc/src/MPEFieldGen/TEXT/readRDMosaicRadars.c index 4845830de6..6df3f8afa5 100644 --- a/nativeLib/rary.ohd.pproc/src/MPEFieldGen/TEXT/readRDMosaicRadars.c +++ b/nativeLib/rary.ohd.pproc/src/MPEFieldGen/TEXT/readRDMosaicRadars.c @@ -62,6 +62,18 @@ ******************************************************************************** */ +/* + * * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * May 2014 ptilles Initial creation/ checkin for 14.3.1 + * Dec 12, 2014 16804 cgobs Fix problems with NULL Products' being considered missing, when certain null products + * should be considered all zero fields. (RM 16804 = DIM 17655) + * + * + */ + #include "mpe_fieldgen.h" #define ACC_MIN 0.01 @@ -71,7 +83,7 @@ void readRDMosaicRadars(const char * radarID, const int daa_wind, const int minCoverageDur, const int ignoreDPARadar, - const int ignoreDAARadar, + const int ignoreDAARadar, float radar [ ] [ NUM_DPA_COLS ] , int * radarAvailFlag, short * daa_avail_flag) @@ -120,14 +132,14 @@ void readRDMosaicRadars(const char * radarID, else //try DPA { useDPA = (! ignoreDPARadar && haveUsefulDPARadar(radarID, datetime, dpa_wind, radar, radarAvailFlag)); - + if ( ! useDPA ) { - + /*---------------------------*/ /* set radar to all missing */ /*---------------------------*/ - + for( i = 0; i < NUM_DPA_COLS; i++) { for( j = 0; j < NUM_DPA_COLS; j++) @@ -135,45 +147,45 @@ void readRDMosaicRadars(const char * radarID, radar[i][j] = RADAR_DEFAULT ; } } - - sprintf ( message , "STATUS: radar marked as missing .") ; + + sprintf ( message , "STATUS: radar marked as missing .") ; printMessage(message, logFile); - + } } - + return; } //------------------------------------------------------------------------------------------ -int haveUsefulDAARadar(const char * radarID, const char * datetime, const int daa_wind, +int haveUsefulDAARadar(const char * radarId, const char * datetime, const int daa_wind, const int minCoverageDur, float radar [ ] [ NUM_DPA_COLS ] , int * radarAvailFlag) { char fname[FNAME_LEN] = "" ; - int i, j ; + int i, j ; int itim, coverageDur, nullProductFlag; int len, ierr ; int haveGoodRadarProduct = 0; double bias, xmax ; - long int irc = 0 ; + long int irc = 0 ; - readDAARadar(radarID, datetime, daa_wind, &xmax, &bias, fname, &itim, + readDAARadar(radarId, datetime, daa_wind, &xmax, &bias, fname, &itim, &coverageDur, &nullProductFlag, &irc) ; - + if(irc == 0) //DAA is available { - - sprintf ( message , "DAA product found for radar = %s\n", radarID) ; + + sprintf ( message , "DAA product found for radar = %s\n", radarId) ; printMessage(message, logFile); - + *radarAvailFlag = 1 ; - + if(itim != 0) { sprintf ( message , "STATUS: no top-of-hour product found -- %d, " @@ -185,204 +197,579 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da ierr = 0 ; - /*---------------------------------------*/ - /* check if product is a null product */ - /*---------------------------------------*/ - if(nullProductFlag == 0) //not a null product - { - sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ; - printMessage(message, logFile); + /*---------------------------------------*/ + /* check if product is a null product */ + /*---------------------------------------*/ + if(nullProductFlag == 0) //not a null product + { + sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ; + printMessage(message, logFile); - sprintf ( message , "reading DAA decoded product with filename = %s\n", fname); - printMessage(message, logFile); + sprintf ( message , "reading DAA decoded product with filename = %s\n", fname); + printMessage(message, logFile); - read_daa_decoded(fname, &len, radar, &ierr) ; - if(ierr != 0) - { + read_daa_decoded(fname, &len, radar, &ierr) ; + + if(ierr != 0) + { /*-------------------------------------------------------*/ /* error reading DAA product - missing data substituted */ /*-------------------------------------------------------*/ - sprintf ( message , "ERROR: #%d encountered reading radar file = %s" + + sprintf ( message , "ERROR: #%d encountered reading radar file = %s" " -- missing data substituted.", ierr, fname ) ; - printMessage(message, logFile); - *radarAvailFlag = 0 ; + printMessage(message, logFile); + + haveGoodRadarProduct = 0; + *radarAvailFlag = 0 ; - for( i = 0; i < NUM_DPA_COLS; i++) - { - for( j = 0; j < NUM_DPA_COLS; j++) - radar[i][j] = RADAR_DEFAULT ; - } - - haveGoodRadarProduct = 0; - - } - else //good product - { - haveGoodRadarProduct = 1; - *radarAvailFlag = 1 ; - } - } - else //this is a null product - { + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = RADAR_DEFAULT ; + } + } - //consider it enough info to say it is 0.0 - if(nullProductFlag == 5 && coverageDur >= minCoverageDur) - /*-----------------------------------------------------------------------------------------*/ - /* if null_product_flag = 5 and coverageDur >= min_coverage_dur then set field to all 0.0 */ - /*-----------------------------------------------------------------------------------------*/ - { - haveGoodRadarProduct = 1; - *radarAvailFlag = 2 ; - sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted."); - printMessage(message, logFile); + else //ierr == 0, which means it is a good product + { + haveGoodRadarProduct = 1; + *radarAvailFlag = 1 ; + } + + } // end if (nullProductFlag == 0) + + else //is a null product of some kind + { - for( i = 0; i < NUM_DPA_COLS; i++) - { - for( j = 0; j < NUM_DPA_COLS; j++) - radar[i][j] = 0.0 ; - } - } - else //consider it missing - { + /*--------------------------------*/ + /* null product processing */ + /*--------------------------------*/ - haveGoodRadarProduct = 0; - *radarAvailFlag = 0 ; - sprintf ( message , "null product with coverage < min coverage or unspecified -- all missing field substituted."); - printMessage(message, logFile); + if(nullProductFlag == 5) + { + + if(coverageDur >= minCoverageDur) + { + /*-----------------------------------------------------------------------------------------*/ + /* if coverageDur >= min_coverage_dur then set field to all 0.0 */ + /*-----------------------------------------------------------------------------------------*/ + haveGoodRadarProduct = 1; + *radarAvailFlag = 2 ; + + sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted."); + printMessage(message, logFile); + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = 0.0 ; + + } + } + + else //coverageDur < minCoverageDur + { + if(isPrevHourNullProdFlag5(radarId, datetime, daa_wind)) + { + /*-------------------------------------------------------------------------------*/ + /* read DAARadar record for previous hour */ + /* if the product for the previous hour also has null_product_flag = 5, */ + /* then set field to all 0.0 */ + /*-------------------------------------------------------------------------------*/ + haveGoodRadarProduct = 1; + *radarAvailFlag = 2 ; + sprintf ( message , "null product flag = 5 for current and previous products -- all 0.0 field substituted."); + printMessage(message, logFile); + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = 0.0 ; + } //end for i + } + + else //not isPrevHourNullProdFlag5 + { + + haveGoodRadarProduct = 0; + *radarAvailFlag = 0 ; + + sprintf ( message , "unacceptable null product with coverage < min coverage or unspecified -- all missing field substituted."); + printMessage(message, logFile); + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = RADAR_DEFAULT ; + } + + } //end else not isPrevHourNullProdFlag5 + } //end else coverageDur < minCoverageDur + } //end if (nullProductFlag == 5) + + + else //does not have a null product flag == 5, so consider it missing + { + + haveGoodRadarProduct = 0; + *radarAvailFlag = 0 ; + sprintf ( message , "null product with coverage < min coverage or unspecified -- all missing field substituted."); + printMessage(message, logFile); + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = RADAR_DEFAULT ; + } + } //end else consider it missing + } //end else is a null product of some kind + + } //end if (irc == 0) -> good read of DAA product + + else //not able to read DAA product + { + + if( isMissingHourCoveredByNullProduct(radarId, datetime, daa_wind)) + { + haveGoodRadarProduct = 1; + *radarAvailFlag = 2 ; + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = 0.0 ; + } //end for i + + sprintf ( message , "haveUsefulDAARadar(): missing hour covered by later hour null product -- all zero field used. "); + printMessage(message, logFile); + + } + + else + { + haveGoodRadarProduct = 0; + *radarAvailFlag = 0 ; + + sprintf ( message , "haveUsefulDAARadar(): data for hour not available -- all missing field used. "); + printMessage(message, logFile); + + } - for( i = 0; i < NUM_DPA_COLS; i++) - { - for( j = 0; j < NUM_DPA_COLS; j++) - radar[i][j] = RADAR_DEFAULT ; - } - } - } //end if null product - } - else //error reading DAA product - { - haveGoodRadarProduct = 0; - *radarAvailFlag = 0 ; - } - +/* + sprintf ( message , "leaving haveUsefulDAARadar(): haveGoodRadarProduct = %d and *radarAvailFlag = %d", + haveGoodRadarProduct, *radarAvailFlag); + printMessage(message, logFile); + +*/ return haveGoodRadarProduct; -} +} //end haveUsefulDAARadar() //------------------------------------------------------------------------------------------ int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dpa_wind, float radar [ ] [ NUM_DPA_COLS ] , int * radarAvailFlag) { - char fname[FNAME_LEN] = "" ; - int i, j ; - int itim; - int len, ierr ; - int haveGoodRadarProduct = 0; - double bias, xmax ; - long int irc = 0 ; + char fname[FNAME_LEN] = "" ; + int i, j ; + int itim; + int len, ierr ; + int haveGoodRadarProduct = 0; + double bias, xmax ; + long int irc = 0 ; - irc = 0; - readDPARadar(radarID, datetime, dpa_wind, &xmax, &bias, fname, &itim, &irc); - - if(irc == 0) //should be a radar file available - { - sprintf ( message , "DPA product found for radar = %s\n", radarID) ; - printMessage(message, logFile); - - } - - if((irc != 0) || (xmax == -99.0)) // dpa radar - { + irc = 0; + readDPARadar(radarID, datetime, dpa_wind, &xmax, &bias, fname, &itim, &irc); - sprintf ( message , " no radar data for current hour" - " -- missing data substituted\n"); - printMessage(message, logFile); + if(irc == 0) //should be a radar file available + { + sprintf ( message , "DPA product found for radar = %s\n", radarID) ; + printMessage(message, logFile); + + } + + if((irc != 0) || (xmax == -99.0)) // dpa radar + { + + sprintf ( message , " no radar data for current hour" + " -- missing data substituted\n"); + printMessage(message, logFile); - haveGoodRadarProduct = 0; + haveGoodRadarProduct = 0; - } - else //read DPA product - { - /*-----------------------------------------*/ - /* xmax > 0.0 -- read decoded DPA product */ - /*-----------------------------------------*/ + } + else //read DPA product + { + /*-----------------------------------------*/ + /* xmax > 0.0 -- read decoded DPA product */ + /*-----------------------------------------*/ - if(xmax > 0.0) - { + if(xmax > 0.0) + { - len = strlen(fname) ; - ierr = 0 ; + len = strlen(fname) ; + ierr = 0 ; - sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ; - printMessage(message, logFile); + sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ; + printMessage(message, logFile); - read_stage1_decoded_(fname, &len, radar, &ierr) ; + read_stage1_decoded_(fname, &len, radar, &ierr) ; - if(ierr != 0) - { - haveGoodRadarProduct = 0; - - sprintf ( message , "ERROR: #%d encountered reading radar file = %s" - " -- missing data substituted.", ierr, fname ) ; - printMessage(message, logFile); - *radarAvailFlag = 0 ; + if(ierr != 0) + { + haveGoodRadarProduct = 0; - for( i = 0; i < NUM_DPA_COLS; i++) - { - for( j = 0; j < NUM_DPA_COLS; j++) - radar[i][j] = RADAR_DEFAULT ; - } - - } - else //product is good, but just check for below minimum and correct to 0.0 - { - haveGoodRadarProduct = 1; - - for( i = 0; i < NUM_DPA_COLS; i++) - { - for( j = 0; j < NUM_DPA_COLS; j++) - { - if(radar[i][j] < ACC_MIN) - radar[i][j] = 0.0 ; - } - } - - - } - } + sprintf ( message , "ERROR: #%d encountered reading radar file = %s" + " -- missing data substituted.", ierr, fname ) ; + printMessage(message, logFile); + *radarAvailFlag = 0 ; + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = RADAR_DEFAULT ; + } + + } + else //product is good, but just check for below minimum and correct to 0.0 + { + haveGoodRadarProduct = 1; + + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + { + if(radar[i][j] < ACC_MIN) + radar[i][j] = 0.0 ; + } + } + + + } + } else //zero product { - haveGoodRadarProduct = 1; - - *radarAvailFlag = 2 ; + haveGoodRadarProduct = 1; + *radarAvailFlag = 2 ; - sprintf ( message , "STATUS: radar data all zero for current hour.") ; - printMessage(message, logFile); + sprintf ( message , "STATUS: radar data all zero for current hour.") ; + printMessage(message, logFile); - if(itim != 0) - { - sprintf ( message , "STATUS: no top-of-hour product found -- %d, " - "product used instead.", itim ) ; - printMessage(message, logFile); - } + if(itim != 0) + { + sprintf ( message , "STATUS: no top-of-hour product found -- %d, " + "product used instead.", itim ) ; + printMessage(message, logFile); + } - for( i = 0; i < NUM_DPA_COLS; i++) - { - for( j = 0; j < NUM_DPA_COLS; j++) - radar[i][j] = 0.0 ; - } + for( i = 0; i < NUM_DPA_COLS; i++) + { + for( j = 0; j < NUM_DPA_COLS; j++) + radar[i][j] = 0.0 ; + } - } + } } return haveGoodRadarProduct; -/* ============== Statements containing RCS keywords: */ -{static char rcs_id1[] = "$Source: /fs/hseb/ob9e/ohd/pproc_lib/src/MPEFieldGen/RCS/readRDMosaicRadars.c,v $"; - static char rcs_id2[] = "$Id: readRDMosaicRadars.c,v 1.4 2012/09/10 19:38:47 pst Exp $";} -/* =================================================== */ +} //end haveUsefulDPARadar() +/*---------------------------------------------------------------------*/ + +int isPrevHourNullProdFlag5(const char * radarId, + const char * datetime, + const int daawind + ) +{ +/* + this function searches the DAARadar table for a record for the previous hour + + if no such top-of-hour record is found, then a search is done on either side + of the hour up to idaawind minutes to look for a record + + if no record is found within the window, then return 0 (false) + + if a record is found, then the value of the nullproductflag is checked + if nullproductflag = 5, then return 1 (true) + else return 0 (false) + + calling subroutine: readRDMosaicRadars +*/ + + int found = 0; + int result = 0; + int minOff = 0; + int nullProductFlag; + + char where [ 256 ]; + DAARadar * pDAARadarHead = NULL ; + char queryObsTime[ANSI_TIME_LEN + 1]; + + time_t currentHourObsTime = 0; + time_t previousHourObsTime = 0; + + time_t beforeTOHObsTime = 0; + time_t afterTOHObsTime = 0; + + + // memset (radarId, '\0',RADAR_ID_LEN + 1 ); + // strncpy (radarId, radar, RADAR_ID_LEN ); + + /* + sprintf ( message , "radar id = %s obstime = %s daa_wind = %d.\n", rrad, str, idaawind); + printMessage(message, logFile); + */ + /*------------------------------------------------------------------------*/ + /* subtract 1 hour from obstime */ + /*------------------------------------------------------------------------*/ + + yearsec_ansi_to_timet(datetime, ¤tHourObsTime); + + previousHourObsTime = currentHourObsTime - SECONDS_PER_HOUR; + + timet_to_yearsec_ansi(previousHourObsTime, queryObsTime); + + /*------------------------------------------------------------------------*/ + /* search for top-of-hour record from previous hour */ + /*------------------------------------------------------------------------*/ + sprintf ( where , "WHERE radid='%s' AND obstime='%s' ", + radarId, queryObsTime ) ; + + pDAARadarHead = GetDAARadar ( where ); + + if ( pDAARadarHead != NULL ) + { + /* A top-of-hour record from previous hour has been found. */ + nullProductFlag = pDAARadarHead->null_product_flag; + found = 1; + + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + } + + else + { + /* Search for non-top-of-hour record. + If searching in window around 00z, then need to use date + of previous day. */ + + for ( minOff = 1; minOff < daawind + 1; minOff ++) + { + /* check after TOH */ + + afterTOHObsTime = previousHourObsTime + (minOff * SECONDS_PER_MINUTE); + timet_to_yearsec_ansi(afterTOHObsTime, queryObsTime); + + sprintf ( where , "WHERE radid='%s' AND obstime='%s' ", + radarId, queryObsTime ) ; + + pDAARadarHead = GetDAARadar ( where ); + + if ( pDAARadarHead != NULL ) + { + /* A record has been found. */ + nullProductFlag = pDAARadarHead->null_product_flag; + found = 1; + + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + break ; + } + + /* check before TOH */ + + beforeTOHObsTime = previousHourObsTime - (minOff * SECONDS_PER_MINUTE); + timet_to_yearsec_ansi(beforeTOHObsTime, queryObsTime); + + sprintf ( where , "WHERE radid='%s' AND obstime='%s' ", + radarId, queryObsTime ) ; + + pDAARadarHead = GetDAARadar ( where ); + + if ( pDAARadarHead != NULL ) + { + /* A record has been found. */ + nullProductFlag = pDAARadarHead->null_product_flag; + found = 1 ; + + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + break; + } + } //end for minOff + } +/*-----------------------------------------------------------------*/ + + result = 0; + if ( ( found == 1 ) && (nullProductFlag == 5)) + { + result = 1; + } + + + if ( pDAARadarHead != NULL ) + { + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + } + + return result; + +} //end isPrevHourNullProdFlag5 + + + /*---------------------------------------------------------------------*/ + + +int isMissingHourCoveredByNullProduct(const char * radarId, + const char * datetimeString, + const int daawind) +{ + + // This function determines if a null product for the next hour is available that indicates that there was no precip + // during the period for which the product in question was missing + + int covered = 0; + int minOff = 0; + int nullProductFlag = 0; + int coverageDur = 0; + char where [ 256 ]; + DAARadar * pDAARadarHead = NULL ; + + char queryObsTime[ANSI_TIME_LEN + 1]; + + time_t currentHourObsTime = 0; + time_t nextHourObsTime = 0; + + time_t beforeTOHObsTime = 0; + time_t afterTOHObsTime = 0; + + // memset ( radarId,'\0',RADAR_ID_LEN + 1 ); + // strncpy (radarId,rad, RADAR_ID_LEN ); + + /* + sprintf ( message , "radar id = %s obstime = %s daa_wind = %d.\n", rrad, str, idaawind); + printMessage(message, logFile); + */ + /*------------------------------------------------------------------------*/ + /* add 1 hour to obstime */ + /*------------------------------------------------------------------------*/ + + yearsec_ansi_to_timet(datetimeString, ¤tHourObsTime); + + nextHourObsTime = currentHourObsTime + SECONDS_PER_HOUR; + + timet_to_yearsec_ansi(nextHourObsTime, queryObsTime); + /*------------------------------------------------------------------------*/ + /* search for top-of-hour record from previous hour */ + /*------------------------------------------------------------------------*/ + sprintf ( where , "WHERE radid='%s' AND obstime='%s' ", + radarId, queryObsTime ) ; + + pDAARadarHead = GetDAARadar ( where ); + + if ( pDAARadarHead != NULL ) + { + /* A top-of-hour record from next hour has been found. */ + + covered = isCovered(pDAARadarHead, currentHourObsTime); + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + } + else //there is no record exactly at the top of the hour + { + + + for ( minOff = 1; minOff < daawind + 1; minOff ++) + { + + /* check after TOH */ + + afterTOHObsTime = nextHourObsTime + (minOff * SECONDS_PER_MINUTE); + timet_to_yearsec_ansi(afterTOHObsTime, queryObsTime); + + + sprintf ( where , "WHERE radid='%s' AND obstime='%s' ", + radarId, queryObsTime ) ; + + + sprintf ( message , " after TOH: WHERE clause = :%s:", where); + + printMessage(message, logFile); + + + pDAARadarHead = GetDAARadar ( where ); + + if ( pDAARadarHead != NULL ) + { + covered = isCovered(pDAARadarHead, currentHourObsTime); + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + break; + } + + /* check before TOH */ + + beforeTOHObsTime = nextHourObsTime - (minOff * SECONDS_PER_MINUTE); + timet_to_yearsec_ansi(beforeTOHObsTime, queryObsTime); + + sprintf ( where , "WHERE radid='%s' AND obstime='%s' ", + radarId, queryObsTime ) ; + + + sprintf ( message , " before TOH: WHERE clause = :%s:", where); + + printMessage(message, logFile); + + pDAARadarHead = GetDAARadar ( where ); + + if ( pDAARadarHead != NULL ) + { + covered = isCovered(pDAARadarHead, currentHourObsTime); + FreeDAARadar ( pDAARadarHead ); + pDAARadarHead = NULL; + break; + } + } //end for minutes + } //end else no record at exactly TOH +/*-----------------------------------------------------------------*/ + + return covered; + +} //end isMissingHourCoveredByNullProduct + + +int isCovered(DAARadar *pDAARadar, time_t originalObsTime) +{ + int covered = 0; + + if (pDAARadar != NULL) + { + + int nullProductFlag = pDAARadar->null_product_flag; + int coverageDurInMinutes = pDAARadar->coverage_dur; + + + if ((nullProductFlag == 5) && (coverageDurInMinutes > 0)) + { + + int obstime = pDAARadar->obstime; + + int secondsSinceRain = coverageDurInMinutes * SECONDS_PER_MINUTE; + + time_t noRainSinceTime = obstime - secondsSinceRain; + + if (noRainSinceTime <= originalObsTime) + { + covered = 1; //True + } + } + + } + + return covered; }