/****************************************************************************** README file for TRMM Version 7 algorithm 3A-12. 3A12 product : TMI 0.5 x 0.5 degree gridded monthly mean product Output parameters: Unit float surfacePrecipitation[720][160]; mm/hr float surfaceRain[720][160]; mm/hr float convectPrecipitation[720][160]; mm/hr float cldWater[28][720][160]; g/m^3 float rainWater[28][720][160]; g/m^3 float cldIce[28][720][160]; g/m^3 float snow[28][720][160]; g/m^3 float graupel[28][720][160]; g/m^3 float latentHeat[28][720][160]; C/hr int npixTotal[720][160]; int npixPrecipitation[720][160]; float fractionQuality0[720][160]; % float fractionQuality1[720][160]; % float fractionQuality2[720][160]; % ******************************************************************************/ 1. Overview of 3A-12 1.1 General description Algorithm 3A-12 is to produce global monthly means of surface precipitation rate, rain rate, convective surface precipitation rate and 28 vertical layers hydrometeor contents (cloud liquid water, rain water, cloud ice liquid water, snow liquid water, graupel liquid water and latent heating) for 0.5 x 0.5 degree grids. For each grid, the monthly total pixel counts (with pixelStatus equal to 0) and precipitation pixel counts (with surfacePrecipitation greater than 0, if over ocean, probabilityOfPrecip greater than 50 % is also required) are also reported. The fraction of total pixels with qualityFlag equal to 0, 1 and 2 are reported as well. qualityFlag is a qualitative flag in GPROF2008 to guide users in areas where GPROF 2008 has retrieved rain but with less than optimal confidence. qualityFlag = 0 means highest confidence. qualityFlag = 1 is used to identify pixels that are probably good but climate trends and very small signals should not be taken from these. Pixels with a small sun glint angle, for instance, are identified in this category. qualityFlag = 2 should be used primarily for qualitative purposes. This category, for instance, identifies areas where GPROF databases were searched far beyond the appropriate SST and TPW bin before a solution could be found. All the means and pixel counts include ambiguous pixels. 1.2 Data accumulation logic for V7 3A12 /* only use 2A12 scans with scanStatus.dataQuality == 0 (good scan) */ if(scanData->scanStatus.dataQuality == 0) { for(i = 0; i < NPIX; i++) { /*** check if lat. & lon. are within limits ***/ if(rangeCheck(scanData->Latitude[i],MIN_LAT,MAX_LAT)==0 && rangeCheck(scanData->Longitude[i],MIN_LON,MAX_LON) == 0) { /*** grid into GRIDSIZE ***/ gridIndex(scanData->Latitude[i],scanData->Longitude[i],(float)GRIDSIZE,&gi_lat,&gi_lon); /* data accumulation */ if(scanData->pixelStatus[i] == 0) /* include valid and ambiguous pixels but exclude sea ice pixels*/ { sfcPrecip=scanData->surfacePrecipitation[i]; sfcRain=scanData->surfaceRain[i]; convPrecip=scanData->convectPrecipitation[i]; if(sfcPrecip > 0.0) { intm->surfacePrecipitation[gi_lon][gi_lat]+=sfcPrecip; /* accumulate precipitating pixel numbers */ if(scanData->surfaceType[i]==10) /* over ocean */ { if(scanData->probabilityOfPrecip[i] > 50) intm->npixPrecipitation[gi_lon][gi_lat]++; } else intm->npixPrecipitation[gi_lon][gi_lat]++; } /* accumulate pixel counts for each qualityFlag value */ if(scanData->qualityFlag[i]==0) intm->fractionQuality0[gi_lon][gi_lat]+= 1.0;; if(scanData->qualityFlag[i]==1) intm->fractionQuality1[gi_lon][gi_lat]+= 1.0;; if(scanData->qualityFlag[i]==2) intm->fractionQuality2[gi_lon][gi_lat]+= 1.0;; if(sfcRain > 0.) intm->surfaceRain[gi_lon][gi_lat]+=sfcRain; if(convPrecip > 0.) intm->convectPrecipitation[gi_lon][gi_lat]+=convPrecip; /* compute NLAYR profile for NSPECIES species */ fhi=scanData->freezingHeightIndex[i]; /* has values 1-13 */ for(s = 0; s < NSPECIES; s++) { cn=scanData->clusterNumber[i][s]; /* has values 1-100 */ cs=scanData->clusterScale[i][s]; for(k = 0; k < NLYR; k++) profile[k][s] = cs * dataHeader->cluster[cn-1][k][fhi-1][s]; } /* accumulate hydrometeor structures */ for(k = 0; k < NLYR; k++) { intm->cldWater[k][gi_lon][gi_lat]+=profile[k][0]; intm->rainWater[k][gi_lon][gi_lat]+=profile[k][1]; intm->cldIce[k][gi_lon][gi_lat]+=profile[k][2]; intm->snow[k][gi_lon][gi_lat]+=profile[k][3]; intm->graupel[k][gi_lon][gi_lat]+=profile[k][4]; intm->latentHeat[k][gi_lon][gi_lat]+=profile[k][5]; } /* accumulate total pixel numbers*/ intm->npixTotal[gi_lon][gi_lat]++; } } } } 1.3 Data averaging logic for V7 3A12 At the end of the month, monthly uncondictional means are computed for each grid: for (j = 0; j < NLON; j++) { for (i = 0; i < NLAT; i++) { /* Compute monthly means */ npix_total = (float)param->npixTotal[j][i]; if (npix_total > 0.) { param->surfacePrecipitation[j][i] = param->surfacePrecipitation[j][i]/npix_total; param->surfaceRain[j][i] = param->surfaceRain[j][i]/npix_total; param->convectPrecipitation[j][i] = param->convectPrecipitation[j][i]/npix_total; /* Compute Fraction Quality values */ param->fractionQuality0[j][i] = 100.0 * param->fractionQuality0[j][i]/npix_total; param->fractionQuality1[j][i] = 100.0 * param->fractionQuality1[j][i]/npix_total; param->fractionQuality2[j][i] = 100.0 * param->fractionQuality2[j][i]/npix_total; for (k = 0; k < NLYR; k++) { param->cldWater[k][j][i] = param->cldWater[k][j][i]/npix_total; param->rainWater[k][j][i] = param->rainWater[k][j][i]/npix_total; param->cldIce[k][j][i] = param->cldIce[k][j][i]/npix_total; param->snow[k][j][i] = param->snow[k][j][i]/npix_total; param->graupel[k][j][i] = param->graupel[k][j][i]/npix_total; param->latentHeat[k][j][i] = param->latentHeat[k][j][i]/npix_total; } } else /* fill in missing value */ { param->surfacePrecipitation[j][i] = MISS_FLT; param->surfaceRain[j][i] = MISS_FLT; param->convectPrecipitation[j][i] = MISS_FLT; param->fractionQuality0[j][i] = MISS_FLT; param->fractionQuality1[j][i] = MISS_FLT; param->fractionQuality2[j][i] = MISS_FLT; for (k = 0; k < NLYR; k++) { param->cldWater[k][j][i] = MISS_FLT; param->rainWater[k][j][i] = MISS_FLT; param->cldIce[k][j][i] = MISS_FLT; param->snow[k][j][i] = MISS_FLT; param->graupel[k][j][i] = MISS_FLT; param->latentHeat[k][j][i] = MISS_FLT; } } } /* end of i = */ } /* end of j = */ 2. Process of 3A-12 The algorithm 3A-12 is executed once per granule. For each execution, output data of 2A-12 are read and then gridded into 0.5 X 0.5 degree boxes. Accumulations are performed for all the parameters and saved in an intermediate data file which is read and updated for each execution. While reading data of 2A-12 ,month period flag (begin/middle/end) is checked. For the granule in the beginning (or end) of one month, data from the previous (or next) month are skipped. For the granule in the middle of one month, all data are processed. If the flag indicates the beginning of a month, the 3A-12 will perform the initialization. If the flag indicates the end of a month, monthly means are computed for 0.5 x 0.5 degree boxes. Then the 3A-12 products are written into its output file in HDF format. 3. Command line inputs of 3A-12 The command line for executing 3A-12 is as follows: L3A12main <2A12 file id> <3A12 file id> where L3A12main: name of 3A-12 executable file; the job name, usually given by Scheduler. <2A12 file id>: name of 2A-12 HDF file. This file is used (read only) for each execution. <3A12 file id>: name of 3A-12 HDF file. This file is used (write only) only for execution of the last granule in one month (i.e. when the month period flag is 'end'). : name of 3A-12 intermediate binary data file. This file is used (read and update) for each execution. : name of 3A-12 intermediate metadata file. This file is used (read and update) for each execution. : name of 3A-12 verification intermediate ASCII file. This file is used (written) for each execution. : character string which indicates whether the current granule is either at the beginning or end of the processing month. : 4-byte character string indicating the year of the current granule : 2-byte character string indicating the month of the current granule All above arguments are needed for each execution. 4. Error/Warning messages E_3A12_ERROR_OPENING_LOGFILE "E_3A12_ERROR_OPENING_LOGFILE - Error opening 3A-12 log file." E_3A12_ERROR_OPENING_2A12FILE "E_3A12_ERROR_OPENING_2A12FILE - Error opening 2A-12 file." E_3A12_ERROR_OPENING_3A12FILE "E_3A12_ERROR_OPENING_3A12FILE - Error opening 3A-12 file." E_3A12_ERROR_OPENING_INTMFILE "E_3A12_ERROR_OPENING_INTMFILE - Error opening intermediate monthly data file." E_3A12_ERROR_READING_2A12METADATA "E_3A12_ERROR_READING_2A12METADATA - Error reading 2A-12 metadata." E_3A12_ERROR_READING_2A12FILE "E_3A12_ERROR_READING_2A12FILE - Error reading 2A-12 file." E_3A12_ERROR_READING_INTMFILE "E_3A12_ERROR_READING_INTMFILE - Error reading intermediate monthly data file." E_3A12_ERROR_READING_INTMMETAFILE "E_3A12_ERROR_READING_INTMMETAFILE - Error reading intermediate metadata file." E_3A12_ERROR_WRITING_INTMFILE "E_3A12_ERROR_WRITING_INTMFILE - Error writing intermediate monthly data file." E_3A12_ERROR_WRITING_INTMMETAFILE "E_3A12_ERROR_WRITING_INTMMETAFILE - Error writing intermediate metadata file." E_3A12_ERROR_WRITING_3A12METADATA "E_3A12_ERROR_WRITING_3A12METADATA - Error writing 3A-12 metadata." E_3A12_ERROR_WRITING_3A12FILE "E_3A12_ERROR_WRITING_3A12FILE - Error writing 3A-12 file." E_3A12_ERROR_CLOSING_LOGFILE "E_3A12_ERROR_CLOSING_LOGFILE - Error closing 3A-12 log file." E_3A12_ERROR_CLOSING_2A12FILE "E_3A12_ERROR_CLOSING_2A12FILE - Error closing 2A-12 file." E_3A12_ERROR_CLOSING_3A12FILE "E_3A12_ERROR_CLOSING_3A12FILE - Error closing 3A-12 file." E_3A12_ERROR_CLOSING_INTMFILE "E_3A12_ERROR_CLOSING_INTMFILE - Error closing intermediate monthly data file." E_3A12_ERROR_REWINDING_INTMFILE "E_3A12_ERROR_REWINDING_INTMFILE - Error rewinding intermediate monthly data file." E_3A12_INCORRECT_NUM_ARGS "E_3A12_INCORRECT_NUM_ARGS - Incorrect number of command line arguments." E_3A12_INVALID_MONTH_PERIOD_FLAG "E_3A12_INVALID_MONTH_PERIOD_FLAG - Invalid begin/middle/end month period flag." E_3A12_NOT_ENOUGH_MEMORY "E_3A12_NOT_ENOUGH_MEMORY - Not enough memory." E_3A12_INVALID_GRID_RESOLUTION "E_3A12_INVALID_GRID_RESOLUTION - Invalid grid resolution in gridIndex.c." 5. 3A-12 algorithm package The package of the 3A-12 algorithm includes the following files: 1). source codes:(in the directory of src) L3A12main.c --- main routine for algorithm 3A-12. It reads the input 2A-12 data file and then grids them into 0.5 degree boxes. It accumulates daily data and computes the monthly means at the end of the month. The intermediate daily and monthly data files are output at the end of each day and monthly, respectively. Makefile --- makefile for 3A-12. averageMon.c --- compute monthly averages of various parameters for each grid box getTMIdata.c --- reads the input 2A-12 data file scan by scan and then grids them into 0.5x0.5 degree boxes addToInterm.c -- adding the daily accumulated data to the interm. data file gridIndex.c --- converts the latitude and longitude in degrees to those in indices of grid boxes initMon.c --- initialize the arrays for monthly intermediate data file output.c --- writes the output of 3A-12 into a HDF file and fills in the follwoing metadata elements: Beginning Date, Beginning Time, Ending Date and Ending Time. rangeCheck.c --- check if a variable is within its dynamic range 2). include files:(in the directory of inc) params.h --- constants which are used in 3A-12 protos.h --- function declarations TK_3A12messages.h --- defines error messages 3). ancillary files: (in the directory of doc) README --- this file 6. Data formats The details of data formats and explanations for standard TRMM products (3A-12) can be found in Reference [1] and [2]. The following is the data structure for the intermediate accumulation data file: typedef struct { float surfacePrecipitation[720][160]; float surfaceRain[720][160]; float convectPrecipitation[720][160]; float cldWater[28][720][160]; float rainWater[28][720][160]; float cldIce[28][720][160]; float snow[28][720][160]; float graupel[28][720][160]; float latentHeat[28][720][160]; int npixTotal[720][160]; int npixPrecipitation[720][160]; float fractionQuality0[720][160]; float fractionQuality1[720][160]; float fractionQuality2[720][160]; } L3A12_GRID; 7. Paramemters in the output data file surfacePrecipitation (4-byte float, array size: nlat x nlon): The monthly mean of the instantaneous precipitation rate at the surface for each grid. Values range from 0 to 3000 mm/hr. Special values are defined as: -9999.9 Missing value surfaceRain (4-byte float, array size: nlat x nlon): The monthly mean of the instantaneous rain rate (liquid portion of precipitation) at the surface for each grid. Values range from 0 to 3000 mm/hr. Special values are defined as: -9999.9 Missing value convectPrecipitation (4-byte float, array size: nlat x nlon): The monthly mean of the instantaneous convective precipitation rate at the surface for each grid. Values range from 0 to 3000 mm/hr. Special values are defined as: -9999.9 Missing value cldWater (4-byte float, array size: nlat x nlon x nlayer): The monthly mean of the cloud liquid water content for each grid at each vertical layer. Values range from 0 to 10 g/m3 . Special values are defined as: -9999.9 Missing value rainWater (4-byte float, array size: nlat x nlon x nlayer): The monthly mean of the rain water content for each grid at each vertical layer. Values range from 0 to 10 g/m3 . Special values are defined as: -9999.9 Missing value cldIce (4-byte float, array size: nlat x nlon x nlayer): The monthly mean of the cloud ice liquid water content for each grid at each vertical layer. Values range from 0 to 10 g/m3 . Special values are defined as: -9999.9 Missing value snow (4-byte float, array size: nlat x nlon x nlayer): The monthly mean of the snow liquid water content for each grid at each vertical layer. Values range from 0 to 10 g/m3 . Special values are defined as: -9999.9 Missing value graupel (4-byte float, array The monthly mean of the graupel liquid water content for each grid at each vertical layer. Values range from 0 to 10 g/m3 . Special values are defined as: -9999.9 Missing value latentHeat (4-byte float, array size: nlat x nlon x nlayer): The monthly mean of the latent heating release for each grid at each vertical layer. Values range from -256 to 256 C/hr. Special values are defined as: -9999.9 Missing value npixTotal (4-byte integer, array size: nlat x nlon): The monthly number of pixels with pixelStatus equal to zero for each grid. The major effect of the pixelStatus requirement is to remove sea ice. npixTotal is used to compute the monthly means described above. Values range from 0 to 10000. Special values are defined as: -9999 Missing value npixPrecipitation (4-byte integer, array size: nlat x nlon): The monthly number of pixels with surfacePrecipitation greater than 0 for each grid. For ocean, a pixel is also required to have probabilityOfPrecip greater than 50 percent. Values range from 0 to 10000. Special values are defined as: -9999 Missing value fractionQuality0 (4-byte float, array size: nlat x nlon): The fraction of total pixels with qualityFlag equal to 0 (high quality) for each grid. Values range from 0 to 100 percent. Special values are defined as: -9999.9 Missing value fractionQuality1 (4-byte float, array size: nlat x nlon): The fraction of total pixels with qualityFlag equal to 1 (medium quality) for each grid. Values range from 0 to 100 percent. Special values are defined as: -9999.9 Missing value fractionQuality2 (4-byte float, array size: nlat x nlon): The fraction of total pixels with qualityFlag equal to 2 (low quality) for each grid. Values range from 0 to 100 percent. Special values are defined as: -9999.9 Missing value 8 Major code changes from V6 (1) use TKIO toolkit instead of TSDIS toolkit for I/O (2) command line usage added and (3) 2A12 input file data format/parameters changed (4) 3A12 output file data format/parameters changed V6 output parameters: float surfaceRain[1][720][160]; float convectRain[1][720][160]; float stratiformRain[1][720][160]; float cldWater[1][14][720][160]; float precipWater[1][14][720][160]; float cldIce[1][14][720][160]; float precipIce[1][14][720][160]; float latentHeat[1][14][720][160]; int npixTotal[1][720][160]; int npixRain[1][720][160]; int npixConvectRain[1][720][160]; int npixStratiformRain[1][720][160]; int npixUnclassifiable[1][720][160]; int npixAmbiguous[1][720][160]; V7 output parameters: float surfacePrecipitation[720][160]; float surfaceRain[720][160]; float convectPrecipitation[720][160]; float cldWater[28][720][160]; float rainWater[28][720][160]; float cldIce[28][720][160]; float snow[28][720][160]; float graupel[28][720][160]; float latentHeat[28][720][160]; int npixTotal[720][160]; int npixPrecipitation[720][160]; float fractionQuality0[720][160]; float fractionQuality1[720][160]; float fractionQuality2[720][160]; (5) data accumulation logic changed V6 used the following accumulation logic: if(scanData->scanStatus.geoQuality <= 4 && scanData->scanStatus.missing != 1 && scanData->scanStatus.validity == 0) { for(i = 0; i < NPIX; i++) { /*** check if lat. & lon. are within limits ***/ if(rangeCheck(scanData->geolocation[i][0],MIN_LAT,MAX_LAT) == 0 && rangeCheck(scanData->geolocation[i][1],MIN_LON, MAX_LON) == 0) { /*** grid 0.5 degree ***/ gridIndex(scanData->geolocation[i][0],scanData->geolocation[i][1],0.5,&gi_lat,&gi_lon); /* accumulate rainrate and pixel numbers*/ sfcrain=scanData->surfaceRain[i]; if(rangeCheck(sfcrain,MIN_RATE,MAX_RATE)== 0) /* include pixels with 0 <= sfcrain <= 500*/ { intm->npixTotal[gi_lon][gi_lat]++; convrain=scanData->convectRain[i]; if(sfcrain > 0.) { intm->npixRain[gi_lon][gi_lat]++; /*** count number of raining pixels ***/ intm->surfaceRain[gi_lon][gi_lat]+=sfcrain; if(convrain > 0.) { /*** count number of convective_raining pixels ***/ intm->npixConvectRain[gi_lon][gi_lat]++; intm->convectRain[gi_lon][gi_lat]+=convrain; intm->stratiformRain[gi_lon][gi_lat]+=(sfcrain-convrain); /*** count number of stratiform_raining pixels ***/ if(sfcrain > convrain) intm->npixStratiformRain[gi_lon][gi_lat]++; } else if(convrain == 0.0) { intm->stratiformRain[gi_lon][gi_lat]+=sfcrain; /*** count number of stratiform_raining pixels ***/ intm->npixStratiformRain[gi_lon][gi_lat]++; } else /* if( convrain <= -9999.0 )*/ { /* count the number of unclassifiable pixel */ intm->npixUnclassifiable[gi_lon][gi_lat]++; } } /* end if ( sfcrain > 0.) */ if( sfcrain == 0.0 && convrain < -9999.0 ) { /* count the number of unclassifiable pixel */ intm->npixUnclassifiable[gi_lon][gi_lat]++; } /* accumulate hydrometeor structure */ for(k = 0; k < NLYR; k++) { intm->precipWater[k][gi_lon][gi_lat]+=scanData->precipWater[i][k]; intm->precipIce[k][gi_lon][gi_lat]+=scanData->precipIce[i][k]; intm->cldWater[k][gi_lon][gi_lat]+=scanData->cldWater[i][k]; intm->cldIce[k][gi_lon][gi_lat]+=scanData->cldIce[i][k]; intm->latentHeat[k][gi_lon][gi_lat]+=scanData->latentHeat[i][k]; } /* counting ambiguous pixels */ if(scanData->rainFlag[i] > 0 ) intm->npixAmbiguous[gi_lon][gi_lat]++; } /* end of if(rangeCheck(sfcerain[i]... */ } /* end of if(rangeCheck(geolation.. */ } /* end of for(i... */ }/* end of if(geoQuality...*/ For V7 accumulation logic, please see section 1.2 Data accumulation logic for V7 3A12. 9. References [1] File Specifications for TRMM Products - Version 7.00 [2] Metadata for TRMM Products - Version 7.00