Merge "VLab Issue #5615 MPE:Null DAA Radar Product Handling; fixes #5615" into ohd_14.4.1

Former-commit-id: f528052db20001235c2b5e97494613cc784a5f36
This commit is contained in:
Chip Gobs 2014-12-12 19:41:12 +00:00 committed by Gerrit Code Review
commit 264b0de297
2 changed files with 563 additions and 175 deletions

View file

@ -12,7 +12,7 @@
* DATE PROGRAMMER DESCRIPTION/REASON * DATE PROGRAMMER DESCRIPTION/REASON
* 9/15/2006 P Tilles added lid to structure gage_radar_pair_struct * 9/15/2006 P Tilles added lid to structure gage_radar_pair_struct
* August 2008 P Tilles added arrays for Q2 * 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 "get_os_system.h"
#include "convert_hrap.h" /* Hrap to LatLon Conversion utilities */ #include "convert_hrap.h" /* Hrap to LatLon Conversion utilities */
#include "time_convert.h" #include "time_convert.h"
#include "DAARadar.h"
#include "HourlyPC.h" #include "HourlyPC.h"
#include "mpe_write_xmrg.h" #include "mpe_write_xmrg.h"

View file

@ -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" #include "mpe_fieldgen.h"
#define ACC_MIN 0.01 #define ACC_MIN 0.01
@ -149,7 +161,7 @@ void readRDMosaicRadars(const char * radarID,
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
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 ] , const int minCoverageDur, float radar [ ] [ NUM_DPA_COLS ] ,
int * radarAvailFlag) int * radarAvailFlag)
@ -163,13 +175,13 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
double bias, xmax ; 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) ; &coverageDur, &nullProductFlag, &irc) ;
if(irc == 0) //DAA is available 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); printMessage(message, logFile);
*radarAvailFlag = 1 ; *radarAvailFlag = 1 ;
@ -197,14 +209,18 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
printMessage(message, logFile); printMessage(message, logFile);
read_daa_decoded(fname, &len, radar, &ierr) ; read_daa_decoded(fname, &len, radar, &ierr) ;
if(ierr != 0) if(ierr != 0)
{ {
/*-------------------------------------------------------*/ /*-------------------------------------------------------*/
/* error reading DAA product - missing data substituted */ /* 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 ) ; " -- missing data substituted.", ierr, fname ) ;
printMessage(message, logFile); printMessage(message, logFile);
haveGoodRadarProduct = 0;
*radarAvailFlag = 0 ; *radarAvailFlag = 0 ;
for( i = 0; i < NUM_DPA_COLS; i++) for( i = 0; i < NUM_DPA_COLS; i++)
@ -212,27 +228,34 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
for( j = 0; j < NUM_DPA_COLS; j++) for( j = 0; j < NUM_DPA_COLS; j++)
radar[i][j] = RADAR_DEFAULT ; radar[i][j] = RADAR_DEFAULT ;
} }
haveGoodRadarProduct = 0;
} }
else //good product
else //ierr == 0, which means it is a good product
{ {
haveGoodRadarProduct = 1; haveGoodRadarProduct = 1;
*radarAvailFlag = 1 ; *radarAvailFlag = 1 ;
} }
}
else //this is a null product } // end if (nullProductFlag == 0)
else //is a null product of some kind
{ {
//consider it enough info to say it is 0.0 /*--------------------------------*/
if(nullProductFlag == 5 && coverageDur >= minCoverageDur) /* null product processing */
/*-----------------------------------------------------------------------------------------*/ /*--------------------------------*/
/* if null_product_flag = 5 and coverageDur >= min_coverage_dur then set field to all 0.0 */
/*-----------------------------------------------------------------------------------------*/ if(nullProductFlag == 5)
{ {
if(coverageDur >= minCoverageDur)
{
/*-----------------------------------------------------------------------------------------*/
/* if coverageDur >= min_coverage_dur then set field to all 0.0 */
/*-----------------------------------------------------------------------------------------*/
haveGoodRadarProduct = 1; haveGoodRadarProduct = 1;
*radarAvailFlag = 2 ; *radarAvailFlag = 2 ;
sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted."); sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted.");
printMessage(message, logFile); printMessage(message, logFile);
@ -240,9 +263,52 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
{ {
for( j = 0; j < NUM_DPA_COLS; j++) for( j = 0; j < NUM_DPA_COLS; j++)
radar[i][j] = 0.0 ; radar[i][j] = 0.0 ;
} }
} }
else //consider it missing
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; haveGoodRadarProduct = 0;
@ -255,19 +321,50 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
for( j = 0; j < NUM_DPA_COLS; j++) for( j = 0; j < NUM_DPA_COLS; j++)
radar[i][j] = RADAR_DEFAULT ; radar[i][j] = RADAR_DEFAULT ;
} }
} } //end else consider it missing
} //end if null product } //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 //error reading DAA product
else
{ {
haveGoodRadarProduct = 0; haveGoodRadarProduct = 0;
*radarAvailFlag = 0 ; *radarAvailFlag = 0 ;
sprintf ( message , "haveUsefulDAARadar(): data for hour not available -- all missing field used. ");
printMessage(message, logFile);
} }
}
/*
sprintf ( message , "leaving haveUsefulDAARadar(): haveGoodRadarProduct = %d and *radarAvailFlag = %d",
haveGoodRadarProduct, *radarAvailFlag);
printMessage(message, logFile);
*/
return haveGoodRadarProduct; return haveGoodRadarProduct;
} } //end haveUsefulDAARadar()
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dpa_wind, int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dpa_wind,
@ -356,7 +453,6 @@ int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dp
else //zero product else //zero product
{ {
haveGoodRadarProduct = 1; haveGoodRadarProduct = 1;
*radarAvailFlag = 2 ; *radarAvailFlag = 2 ;
sprintf ( message , "STATUS: radar data all zero for current hour.") ; sprintf ( message , "STATUS: radar data all zero for current hour.") ;
@ -380,9 +476,300 @@ int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dp
return haveGoodRadarProduct; return haveGoodRadarProduct;
/* ============== Statements containing RCS keywords: */ } //end haveUsefulDPARadar()
{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 $";} /*---------------------------------------------------------------------*/
/* =================================================== */
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, &currentHourObsTime);
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, &currentHourObsTime);
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;
}