/* * Copyright(c) 1997, Space Science and Engineering Center, UW-Madison * Refer to "McIDAS Software Acquisition and Distribution Policies" * in the file mcidas/data/license.txt */ /**** $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ ****/ /* ** Name: ** modsaget : ADDE image server for MODIS HDF-EOS image files. ** ** Interface: ** int ** main(int argc, char *argv[]) ** ** Input: ** argc : argument count ** argv : argument vector ** ** Input and Output: ** none ** ** Output: ** none ** ** Return values: ** 0 : success ** < 0 : failure, enumerated by text message returned to client ** ** Remarks: ** This program is reads HDF-EOS format of MODIS data ** ** Categories: ** ADDE server */ #include #include #include #include #include "mcidas.h" #include "mcidasp.h" #include "AreaDir.h" #include "m0glue.h" #include "m0arg.h" #include "mfhdf.h" #include "hdf.h" /* Prototypes */ int TEMPtoBRIT( int, float ); float MODISbright( float, int, int, int ); float MODISplanck( float, int, int, int ); float brightm( float, float ); float planckm( float, float ); float britem( float, float ); float plancm( float, float ); int main ( int argc, char *argv[] ) #define TRUE 1 #define FALSE 0 #define DIR_SIZE 64 #define IMAGE_FILE_VERSION 4 #define TERRA_RAW 101 #define TERRA_PRODUCT 102 #define AQUA_RAW 111 #define AQUA_PRODUCT 112 #define MAX_STR_LEN 80 #define MAX_BANDS 64 { /* MODIS constants */ int MODIS_NAV_OFFSET = 256; /* NAV block offset */ int MODIS_CAL_OFFSET = 768; /* CAL block offset */ int MODIS_AUX_OFFSET = 1684; /* AUX block offset */ int AUX_MAGIC_NUMBER = 0x04030201; /* AUX block magic number */ int MODIS_AUX_ENTRIES = 2; /* AUX block entries */ int MODIS_LAT_AUX = 24; /* AUX block: LAT entry header byte size */ int MODIS_LON_AUX = 28; /* AUX block: LON entry header byte size */ int NAV_BLOCK_SIZE = 128; /* NAV block word size */ int CAL_BLOCK_SIZE = 229; /* CAL block word size */ float MODIS_RAW_SCALE = 1. ; /* scaling for RAW data */ float MODIS_RAD_SCALE = 1000. ; /* scaling for RAD data */ float MODIS_RADN_SCALE = 1000. ; /* scaling for RADN data */ float MODIS_REF_SCALE = 1000. ; /* scaling for REF data */ float MODIS_RERA_SCALE = 1000. ; /* scaling for RERA data */ float MODIS_TEMP_SCALE = 100. ; /* scaling for TEMP data */ float MODIS_BRIT_SCALE = 1. ; /* scaling for BRIT data */ /* variables used: */ const char *dum; /* dummy variable for arg routines */ const char server[]={"MODSAGET"}; /* server name */ static char trace_string[500]; /* tracing text */ /* dynamic command buffers */ char cmd[512]; char string[180]; char stretch_name[2]; char level_map[MAX_BANDS]; /* prefix level map */ char *dataset; /* dataset name */ char *def_unit; /* default UNIT */ char *dir_unit; /* directory UNIT */ char *cdate; /* file date chars */ char *chms; /* file time chars */ char *comment; /* ADDE comment field */ char *cname; /* file name */ char *csstr; /* UNITS ORIG or EXP stretch */ char *format; /* ADDE dataset format */ char *group; /* dataset group */ char *info; /* ADDE dataset info */ char *mask; /* dataset file mask */ char *place; /* coordinate system */ char *navproj; /* NAV projection */ char *navpole; /* NAV pole */ char *punit; /* parameter UNITS */ char *request; /* request string */ char *type; /* ADDE dataset type */ char *unit; /* UNITS keyword */ char **flist = NULL; /* hdf file list */ char *file_list[1000]; /* screened hdf file list */ char *of_dat; char *of_hdr; char geo_string[6]; char hdr_string[6]; /* char of_string[12]; */ char of_string[40]; float temp; /* temperature */ float raw; /* raw count */ float rad; /* radiance */ float radn; /* radiance */ float rbrit; /* float of BRIT */ float ref; /* reflectance */ float rera; /* reflective radiance */ float cnts; /* corrected counts */ float brit; /* brightness */ float lat_diff; /* latitude difference */ float lon_diff; /* longitude difference */ float minimum; /* minimum difference */ Fint4 aux_head[100]; /* AUX entry header */ Fint4 directory[DIR_SIZE]; /* image directory block */ Fint4 nav_block[128]; /* navigation block */ Fint4 cal_block[229]; /* calibration block */ int ONE=1; int TWO=2; int aux_block_size; /* size of the AUX block */ int bands[MAX_BANDS]; /* list of bands */ int band_ptr; /* band loop pointer */ int band_all; /* ALL bands tranfer flag */ int bdate; /* geginning CCYYDDD */ int btime; /* beginning time */ int curDate; /* current CCYYDDD */ int curTime; /* current HHMMSS */ int dat_block_size; /* data block size */ int def_space; /* default SPACE */ int edate; /* ending range date */ int esize; /* image element size */ int etime; /* ending time */ int file_handle; /* file handle */ int hiBound; /* ending dataset position */ int ptr; /* array pointer */ int i; /* loop index */ int ii; /* secondary line index */ int ie; /* secondary line index */ int j; /* loop index */ int jj; /* secondary element index */ int k; /* array index */ int lalo_array_size; /* lat/lon array size */ int lalo_array_line_size; /* lat/lon array line size */ int lalo_array_elem_size; /* lat/lon array elem size */ int loBound; /* starting dataset position */ int length; /* string length */ int num_flist; /* number of files */ int ounit_flag; /* output unit flag */ int pscale; /* parameter scale */ int psize; /* prefix size */ int rc; /* function return code */ int rt_flag; /* ADDE realtime flag */ int space; /* output spacing */ int totalSize; /* transfer byte count */ int trace; /* trace flag */ int transaction = 0; /* transaction flag */ int user = 0; /* user id */ int bad_Latitudes; /* counts number of bad Latitude values */ int bad_Longitudes; /* counts number of bad Longitude values */ int nbad; unsigned int iexp; /* exponent for pow function */ char attr_name[MAX_STR_LEN]; char name[MAX_NC_NAME]; char *char_array; char *cday; char *file_name; char *image_stype; char *last_stype; char *char_band; char *of_pathname; intn status; int32 n_datasets; int32 n_file_attrs; int32 n_attr; int32 index; int32 sd_data_index[MAX_BANDS]; int32 sd_id; int32 sds_id; int32 sds_rank; int32 data_type; int32 sds_data_type; int32 count; int32 sds_n_attrs; int32 sds_dim_sizes[MAX_VAR_DIMS]; int32 start[MAX_VAR_DIMS]; int32 stride[MAX_VAR_DIMS]; int32 edge[MAX_VAR_DIMS]; int band; int bPos; int ePos; int iPos; int scale_index[MAX_BANDS]; int sd_band_index[MAX_BANDS]; int sd_band_num[MAX_BANDS]; int sd_band_rank[MAX_BANDS]; int image_stype_flag; int image_cyd; int image_iyd; int image_hms; int image_n_bands; int image_starting_line; int image_starting_element; int image_dataset_position; int image_satellite_number; int image_line_size; Fint STG_parms[6]; int image_element_size; int image_line_base_resolution; int image_element_base_resolution; int image_selected_band; float image_line_resolution; float image_element_resolution; float DATAtoGEO_line; float DATAtoGEO_element; int image_geo_line_size; int image_geo_element_size; int image_geo_line_magnification; int image_geo_element_magnification; int image_geo_data_size; int image_geo_latitude_resolution; int image_geo_longitude_resolution; int image_geo_nav_offset; int nav_offset; int GotaLALO; int file_name_type; /* file naming convention 1=DACC, 2=DB */ uint8 bit_ZERO; uint8 bit_ONE; uint8 bit_TWO; uint8 bit_THREE; uint8 bit_FOUR; uint8 bit_FIVE; uint8 bit_SIX; uint8 bit_SEVEN; uint8 bit_FILL; uint8 *gflags_array; uint16 *uint16_array; uint16 *Data_array; float image_geo_minimum_latitude; float image_geo_maximum_latitude; float image_geo_minimum_longitude; float image_geo_maximum_longitude; float image_geo_center_latitude; float image_geo_center_longitude; float image_geo_line_resolution; float image_geo_element_resolution; float sector_min_lat; float sector_min_lon; float sector_max_lat; float sector_max_lon; float navparm[10]; float32 radiance_scales[MAX_BANDS]; float32 radiance_offsets[MAX_BANDS]; float32 reflectance_scales[MAX_BANDS]; float32 reflectance_offsets[MAX_BANDS]; float32 corrected_counts_scales[MAX_BANDS]; float32 corrected_counts_offsets[MAX_BANDS]; float32 *float32_array; float32 *Latitude_array; float32 *Longitude_array; double request_center_latitude; double request_center_longitude; int request_data_size; int request_n_bands; int request_bands[MAX_BANDS]; int request_band_type[MAX_BANDS]; int request_lalo_flag; int request_image_flag; int request_area_flag; int request_line_size; int request_element_size; int request_line_resolution; int request_element_resolution; int request_line_magnification; int request_element_magnification; int request_starting_line; int request_starting_element; int lineSampleRate; int elemSampleRate; int read_line_size; int read_element_size; int read_starting_line; int read_starting_element; int read_ending_line; int read_ending_element; int read_geo_line_size; int read_geo_element_size; int read_geo_starting_line; int read_geo_starting_element; int read_geo_ending_line; int read_geo_ending_element; int total_line; int total_elem; int starting_line; int starting_elem; int ending_line; int ending_elem; int test; int found; int add; int extend; int sum; int size; int EV250REFBAND = 0; int EV500REFBAND = 0; int EV1000REFBAND = 0; int EV1000RADBAND = 0; int EVBAND26 = 0; int ev_band26; int HDF_Latitude_flag; int HDF_Longitude_flag; int HDF_All_Data_flag; int HDF_Data_flag[MAX_BANDS]; int HDF_Gflags_flag; int MODIS_1KM_flag; int MODIS_QKM_flag; int MODIS_HKM_flag; int compress_flag; int singleband_flag; int swath2grid_flag = 0; int REQUEST_SIZE_FLAG; int N_tokens; int I_token; int B_token; unsigned char *uchar_array; unsigned short int *ushort_array; unsigned int *ulong_array; float32 *float_array; int nelem; int iline; McArgSyntax filesyntax = {".", "=", ";", "{\"", "}", "'", "'", NULL, "X", " "}; servacct requestBlock; /* request block */ unsigned int value; /* EOS data value */ unsigned short int *McIDAS_2byte_array; /* McIDAS 2 byte array */ /* initialize bit tests */ bit_ZERO = 1; bit_ONE = 2; bit_TWO = 4; bit_THREE = 8; bit_FOUR = 16; bit_FIVE = 32; bit_SIX = 64; bit_SEVEN = 128; bit_FILL = 255; ev_band26 = FALSE; /* initialize local server */ rc = M0InitLocalServer(server, argc, argv, &requestBlock, &request); /* see if logging should be done, determined by hidden TRACE= flag */ trace = M0IsTraceSet(request); if (trace > 0) { (void *)sprintf(trace_string,"\n\n%s TEST MODSAGET Trace level = %d",server,trace); M0sxtrce( trace_string ); } /* move the request back into the comm block */ (void) strncpy(requestBlock.text, request, sizeof(requestBlock.text)); /* fill in the data type */ transaction = atoi(argv[5]); (void) memcpy(requestBlock.transaction, &transaction, sizeof(requestBlock.transaction)); /* fill in the user */ user = atoi(argv[3]); (void) memcpy(requestBlock.user, &user, sizeof(requestBlock.user)); /* initialize accounting */ m0vserv_(&requestBlock); /* get dataset info */ rc = M0sxdatasetinfo(request, &group, &dataset, &type, &format, &mask, &info, &comment, &loBound, &hiBound, &rt_flag); sprintf(trace_string, "%s Group=%s Descriptor=%s", server,group,dataset); M0sxtrce( trace_string ); sprintf(trace_string, "%s File Mask = %s", server,mask); M0sxtrce( trace_string ); /* check for file compression */ compress_flag = FALSE; if( strncmp(info,"HDFCOMPRESS",11) == 0 ) compress_flag = TRUE; /* produce a list of files matching the file mask */ flist = M0GetMaskFileList(mask); if( flist == (char **)NULL ) { (void)strcpy(requestBlock.errormsg, "Failed to generate file mask list"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } num_flist = VecLen(flist); /* make sure there were some files found */ if( num_flist <= 0 ) { (void)strcpy(requestBlock.errormsg, "No files found matching file mask"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* screen the list for crefl files */ j = 0; for( i=0; i= 1 && band <= 2 ) EV250REFBAND = 1; if( band >= 3 && band <= 7 ) EV500REFBAND = 1; if( band >= 8 && band <= 19 ) EV1000REFBAND = 1; if( band >= 37 && band <= 38 ) EV1000REFBAND = 1; if( band >= 20 && band <= 25 ) EV1000RADBAND = 1; if( band >= 27 && band <= 36 ) EV1000RADBAND = 1; if( band == 26 ) EVBAND26 = 1; } } } /* if compressed dataset --> only 1 band is allowed */ singleband_flag = FALSE; if( request_n_bands != 1 ) { if( compress_flag == TRUE ) { (void)strcpy(requestBlock.errormsg, "Compressed Multi-band transfer not allowed"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } else { singleband_flag = TRUE; } /* STYPE */ image_stype_flag = Mcargnum(0, "STY.PE" ); if( image_stype_flag != 0 ) { char *cstype; /* STYPE keyword */ rc = Mcargstr(0, "STY.PE", 1, "VISR", (const char **)&cstype); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid STYPE specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( strncmp( cstype, "VISR",4 ) != 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid STYPE specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "STYPE with Multi-band not allowed"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } image_stype = stralloc( "VISR", NULL); def_unit = stralloc( "BRIT", NULL); last_stype = stralloc( "MODS", NULL); def_space = 1; CAL_BLOCK_SIZE = 0; MODIS_CAL_OFFSET = 0; MODIS_AUX_OFFSET = 768; } else { image_stype = stralloc( "MODS", NULL); def_unit = stralloc( "RAW",NULL); last_stype = stralloc( " ", NULL); def_space = 2; } /* SPACE */ rc = Mcargint(0, "SPA.CE", 1, def_space, 0, 4, &space, &dum); if( rc < 0 || space == 3 ) { (void)strcpy(requestBlock.errormsg, "Invalid SPACE specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* UNIT */ rc = Mcargstr(0, "UNI.T", 1, def_unit, (const char **)&unit); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid UNIT specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } rc = Mcargstr(0, "UNI.T", 2, " ", (const char **)&csstr); if( strncmp( unit, "RAW",3 ) == 0 ) { if( space == 0 ) space = 2; if( space < 2 ) { (void)strcpy(requestBlock.errormsg, "Invalid Spacing for RAW specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "RAW ",NULL); request_data_size = space; pscale = MODIS_RAW_SCALE; punit = stralloc(" ",NULL); ounit_flag = 0; } else if( strncmp( unit, "REF",3 ) == 0 ) { if( space == 0 ) space = 2; if( space < 2 ) { (void)strcpy(requestBlock.errormsg, "Invalid Spacing for REF specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_bands[0] > 19 && request_bands[0] != 26 && request_bands[0] != 37 && request_bands[0] != 38 ) { (void)strcpy(requestBlock.errormsg, "Band is not available in REF units"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "REF ",NULL); request_data_size = space; pscale = MODIS_REF_SCALE; punit = stralloc("1/sr",NULL); ounit_flag = 1; } else if( strncmp( unit, "RERA",4 ) == 0 ) { if( space == 0 ) space = 2; if( space < 2 ) { (void)strcpy(requestBlock.errormsg, "Invalid Spacing for RERA specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_bands[0] > 19 && request_bands[0] != 26 && request_bands[0] != 37 && request_bands[0] != 38 ) { (void)strcpy(requestBlock.errormsg, "Band is not available in RERA units"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "RERA",NULL); request_data_size = space; pscale = MODIS_RERA_SCALE; punit = stralloc("WM**",NULL); ounit_flag = 6; } else if( strncmp( unit, "RADN" ,4) == 0 ) { if( space == 0 ) space = 4; if( space < 4 ) { (void)strcpy(requestBlock.errormsg, "Invalid Spacing for RADN specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_bands[0] < 20 || request_bands[0] == 26 || request_bands[0] > 36 ) { (void)strcpy(requestBlock.errormsg, "Band is not available in RADN units"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "RADN",NULL); request_data_size = space; pscale = MODIS_RADN_SCALE; punit = stralloc("WM**",NULL); ounit_flag = 5; } else if( strncmp( unit, "RAD",3 ) == 0 ) { if( space == 0 ) space = 4; (void *)sprintf(trace_string,"%s BAND[0]=%d",server,request_bands[0]); M0sxtrce( trace_string ); if( space < 4 ) { (void)strcpy(requestBlock.errormsg, "Invalid Spacing for RAD specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_bands[0] < 20 || request_bands[0] == 26 || request_bands[0] > 36 ) { (void)strcpy(requestBlock.errormsg, "Band is not available in RAD units"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "RAD ",NULL); request_data_size = space; pscale = MODIS_RAD_SCALE; punit = stralloc("MW**",NULL); ounit_flag = 2; } else if( strncmp( unit, "TEMP" ,4) == 0 ) { if( space == 0 ) space = 2; if( space < 2 ) { (void)strcpy(requestBlock.errormsg, "Invalid Spacing for TEMP specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_bands[0] < 20 || request_bands[0] == 26 || request_bands[0] > 36 ) { (void)strcpy(requestBlock.errormsg, "Band is not available in TEMP units"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "TEMP",NULL); request_data_size = space; pscale = MODIS_TEMP_SCALE; punit = stralloc("K ",NULL); ounit_flag = 3; } else if( strncmp( unit, "BRIT" ,4) == 0 ) { if( space == 0 ) space = 1; if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "BRIT",NULL); request_data_size = space; pscale = MODIS_BRIT_SCALE; punit = stralloc(" ",NULL); ounit_flag = 4; } else if( strncmp( unit, "CNTS" ,4) == 0 ) { if( space == 0 ) space = 2; if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } dir_unit = stralloc( "CNTS",NULL); request_data_size = space; pscale = MODIS_BRIT_SCALE; punit = stralloc(" ",NULL); ounit_flag = 7; } else { (void)strcpy(requestBlock.errormsg, "Invalid UNIT specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } (void *)sprintf(trace_string,"%s SPACE: %d",server,space); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s UNIT: %s",server,unit); M0sxtrce( trace_string ); /* *** Beginning HDF file access *** */ /* Initialization */ HDF_Latitude_flag = FALSE; HDF_Longitude_flag = FALSE; HDF_Gflags_flag = FALSE; MODIS_1KM_flag = FALSE; MODIS_QKM_flag = FALSE; MODIS_HKM_flag = FALSE; HDF_All_Data_flag = FALSE; for( i=0; i 2 ) { (void)strcpy(requestBlock.errormsg, "Specified BAND not contained in image"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } } else if( strstr( cname, "HKM" ) != NULL || strstr( cname, "500m") != NULL || strstr( cname, "cal500") != NULL ) { image_starting_line = 1; image_starting_element = 1; image_line_base_resolution = 2; image_element_base_resolution = 2; image_line_resolution = 0.50; image_element_resolution = 0.50; image_geo_line_resolution = 1.00; image_geo_element_resolution = 1.00; image_geo_line_magnification = ((request_line_magnification/5)+1)*5; image_geo_element_magnification = ((request_element_magnification/5)+1)*5; image_geo_latitude_resolution = 4; image_geo_longitude_resolution = 4; image_geo_nav_offset = 0; nav_offset = 0; MODIS_HKM_flag = TRUE; HDF_Gflags_flag = TRUE; /* check for ALL bands */ if( band_all == 1 ) { request_n_bands = 7; for( i=0; i 7 ) { (void)strcpy(requestBlock.errormsg, "Specified BAND not contained in image"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } } else if( strstr( cname, "1KM" ) != NULL || strstr( cname, "1000m") != NULL || strstr( cname, "cal1000") != NULL ) { image_starting_line = 1; image_starting_element = 1; image_line_base_resolution = 4; image_element_base_resolution = 4; image_line_resolution = 1.00; image_element_resolution = 1.00; image_geo_line_resolution = 5.00; image_geo_element_resolution = 5.00; image_geo_line_magnification = (request_line_magnification/2)+1; image_geo_element_magnification = (request_element_magnification/2)+1; image_geo_latitude_resolution = 20; image_geo_longitude_resolution = 20; image_geo_nav_offset = 9; nav_offset = 2; MODIS_1KM_flag = TRUE; /* check for ALL bands */ if( band_all == 1 ) { request_n_bands = 38; for( i=0; i 38 ) { (void)strcpy(requestBlock.errormsg, "Specified BAND not contained in image"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } } else { sprintf(trace_string, "%s FILE RESOLUTION: FAILED for %s", server, file_name); M0sxtrce( trace_string ); continue; } /* compute the SSEC resolution of the requested data */ request_line_resolution = image_line_base_resolution * request_line_magnification; request_element_resolution = image_element_base_resolution * request_element_magnification; /* compute the DATA vs GEO array ratio */ DATAtoGEO_line = image_line_resolution / image_geo_line_resolution; DATAtoGEO_element = image_element_resolution / image_geo_element_resolution; /* Evaluate the file name: DAY (CCYYDDD) */ rc = Mcargstr( file_handle, "", B_token+1, "", (const char **)&cdate); length = strlen( cdate ); for( i=0; i edate) ) continue; if( (image_hms < btime) || (image_hms > etime) ) continue; /* start the HDF file */ sd_id = SDstart( file_name, DFACC_READ ); if( sd_id == FAIL ) { sprintf(trace_string, "%s START: FAILED for %s", server, file_name); M0sxtrce( trace_string ); break; } (void *)sprintf(trace_string,"%s SDstart=OK",server); M0sxtrce( trace_string ); /* determine the number of SDS's in the file */ status = SDfileinfo( sd_id, &n_datasets, &n_file_attrs ); if( status == FAIL ) { sprintf(trace_string, "%s FILEINFO FAILED for %s", server, file_name); M0sxtrce( trace_string ); break; } (void *)sprintf(trace_string,"%s SDfileinfo=OK #Attributes=%d", server,n_file_attrs); M0sxtrce( trace_string ); /* loop through the individual SDS's */ for( index=0; indeximage_geo_maximum_latitude ) image_geo_maximum_latitude = Latitude_array[i]; } } if( GotaLALO == 0 ) { return -1; } else { (void *)sprintf(trace_string,"%s Latitude: Min=%f Max=%f",server, image_geo_minimum_latitude, image_geo_maximum_latitude ); M0sxtrce( trace_string ); } /* compute and store center Latitude */ i = ((sds_dim_sizes[0]/2 - 1) * sds_dim_sizes[1]) + (sds_dim_sizes[1]/2) - 1; image_geo_center_latitude = Latitude_array[i]; /* set the Latitude component flag */ HDF_Latitude_flag = TRUE; (void *)sprintf(trace_string,"%s Latitude=OK",server); M0sxtrce( trace_string ); } } } /* Geo Fields - gflags */ if( strncmp( name, "gflags",6 ) == 0 ) { (void *)sprintf(trace_string,"%s FOUND gflags", server); M0sxtrce( trace_string ); /* setup for gflags read */ start[0] = 0; start[1] = 0; stride[0] = 1; stride[1] = 1; edge[0] = sds_dim_sizes[0]; edge[1] = sds_dim_sizes[1]; /* reserve memory for the gflags array */ if( sds_data_type == 21 ) { gflags_array = malloc( (sds_dim_sizes[0]*sds_dim_sizes[1]) ); if( gflags_array != NULL ) { /*read the gflags array */ status = SDreaddata( sds_id, start, stride, edge, gflags_array); if( status == FAIL ) { return -1; } /* set the data component flag */ HDF_Gflags_flag = TRUE; } } } /* Geo Fields - Longitude */ if( strncmp( name, "Longitude",9 ) == 0 ) { (void *)sprintf(trace_string,"%s FOUND Longitude", server); M0sxtrce( trace_string ); /* setup for data read */ start[0] = 0; start[1] = 0; stride[0] = 1; stride[1] = 1; edge[0] = sds_dim_sizes[0]; edge[1] = sds_dim_sizes[1]; /* reserve memory for the Longitude array */ if( sds_data_type == 5 ) { Longitude_array = malloc( (sds_dim_sizes[0]*sds_dim_sizes[1]) * sizeof(float32)); if( Longitude_array != NULL ) { /*read the longitude array */ status = SDreaddata( sds_id, start, stride, edge, Longitude_array); if( status == FAIL ) { return -1; } /* scan for minimum and maximum longitude */ GotaLALO = 0; for (i=0; i<(image_geo_line_size*image_geo_element_size); i++ ) { if( Longitude_array[i] != -999.0 ) { if( GotaLALO == 0 ) { image_geo_minimum_longitude = Longitude_array[i]; image_geo_maximum_longitude = Longitude_array[i]; GotaLALO = 1; } if( Longitude_array[i]image_geo_maximum_longitude ) image_geo_maximum_longitude = Longitude_array[i]; } } if( GotaLALO == 0 ) { return -1; } else { (void *)sprintf(trace_string,"%s Longitude: Min=%f Max=%f",server, image_geo_minimum_longitude, image_geo_maximum_longitude ); M0sxtrce( trace_string ); } /* compute and store center Latitude */ i = ((sds_dim_sizes[0]/2 - 1) * sds_dim_sizes[1]) + (sds_dim_sizes[1]/2) - 1; image_geo_center_longitude = Longitude_array[i]; /* set the Longitude component flag */ HDF_Longitude_flag = TRUE; (void *)sprintf(trace_string,"%s Longitude=OK",server); M0sxtrce( trace_string ); } } } /* Earth View (EV_) Fields */ if( strstr( name, "EV_" ) != NULL || strstr( name, "Band_" ) != NULL ) { (void *)sprintf(trace_string,"%s FOUND %s", server, name); M0sxtrce( trace_string ); /* loop through the request bands */ for( j=0; j 19 && request_bands[j] != 26 && request_bands[j] < 37 ) { request_band_type[j] = 1; } /* Loop through the bands in the data set */ for( i=0; i image_geo_maximum_latitude || request_center_longitude < image_geo_minimum_longitude || request_center_longitude > image_geo_maximum_longitude ) { (void)strcpy(requestBlock.errormsg, "requested Earth location is not contained in the image"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); /* sprintf(trace_string, "%s segment fails lat/lon bounds", server); M0sxtrce( trace_string ); goto SWATH_END_LABEL; */ } /* scan for the closest lat/lon point in geo-fields */ minimum = 999.0; for( i=0; i image_line_size || read_ending_line < 0 || read_starting_element > image_element_size || read_ending_element < 0 ) { (void)strcpy(requestBlock.errormsg, "The portion of the image requested does not exist"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } GEO_REQEST: (void *)sprintf(trace_string,"%s GEO REQUEST",server); M0sxtrce( trace_string ); /* determine the size of the geo request */ read_geo_line_size = read_line_size * DATAtoGEO_line; if( read_geo_line_size <= 1 ) read_geo_line_size = 2; read_geo_element_size = read_element_size * DATAtoGEO_element; if( read_geo_element_size <= 1 ) read_geo_element_size = 2; /* determine the coordinates of the geo request */ read_geo_starting_line = (read_starting_line-nav_offset) * DATAtoGEO_line; if( read_geo_starting_line < 0 ) read_geo_starting_line = 0; test = (read_geo_starting_line/image_geo_line_magnification)*image_geo_line_magnification; if( test != read_geo_starting_line ) { /* read_geo_line_size = read_geo_line_size+1; */ read_geo_starting_line = test; } read_geo_starting_element = (read_starting_element-nav_offset) * DATAtoGEO_element; if( read_geo_starting_element < 0 ) read_geo_starting_element = 0; test = (read_geo_starting_element/image_geo_element_magnification)*image_geo_element_magnification; if( test != read_geo_starting_element ) { /* read_geo_element_size = read_geo_element_size+1; */ read_geo_starting_element = test; } read_geo_ending_line = read_geo_starting_line + read_geo_line_size - 1; test = (read_geo_ending_line/image_geo_line_magnification)*image_geo_line_magnification; if( test != read_geo_ending_line ) { /* read_geo_line_size = read_geo_line_size+1; */ read_geo_ending_line = test + image_geo_line_magnification; } read_geo_ending_element = read_geo_starting_element + read_geo_element_size - 1; test = (read_geo_ending_element/image_geo_element_magnification)*image_geo_element_magnification; if( test != read_geo_ending_element ) { /* read_geo_element_size = read_geo_element_size+1; */ read_geo_ending_element = test + image_geo_element_magnification; } /* reduce the request to only the valid lat/lon points */ if( read_geo_starting_line < 0 ) read_geo_starting_line = 0; if( read_geo_starting_element < 0 ) read_geo_starting_element = 0; if( read_geo_ending_line >= image_geo_line_size ) read_geo_ending_line = image_geo_line_size-1; if( read_geo_ending_element >= image_geo_element_size ) read_geo_ending_element = image_geo_element_size-1; read_geo_line_size = read_geo_ending_line - read_geo_starting_line + 1; read_geo_element_size = read_geo_ending_element - read_geo_starting_element + 1; (void *)sprintf(trace_string,"%s READ GEO: line size=%d",server,read_geo_line_size); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ GEO: element size=%d",server,read_geo_element_size); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ GEO: starting line=%d",server,read_geo_starting_line); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ GEO: starting element=%d",server,read_geo_starting_element); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ GEO: ending line=%d",server,read_geo_ending_line); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ GEO: ending element=%d",server,read_geo_ending_element); M0sxtrce( trace_string ); /* set the line and element sampling rates prior to SwathToGrid check */ lineSampleRate = request_line_magnification; elemSampleRate = request_element_magnification; /* Dynamic execution of MRTSwath */ if( strncmp(navproj,"MERC",4) == 0 || strncmp(navproj,"LAMB",4) == 0 || strncmp(navproj,"RECT",4) == 0 || strncmp(navproj,"PS",2) == 0 ) { char *dummyFile; char *geo_name; char *of_name; char *of_path; char llchar[4] = {"LL "}; int LL; int pixelSize; Freal Flat; Freal Flon; Freal Flat_UL; Freal Flon_UL; Freal Flat_LR; Freal Flon_LR; Freal dummy; Freal Fline; Freal Felem; Freal Fline_UL; Freal Felem_UL; Freal Fline_LR; Freal Felem_LR; Freal Latitude_diff; Freal Longitude_diff; Freal DPL; Freal DPE; float temp_res; float temp_mag; int SMajor = 6378137; int SMinor = 6356753; int PP[16]; Freal LongPol; Freal TrueScale; Freal StdPr1; Freal StdPr2; Freal CentMer; Freal OriginLat; for( i=0; i<16; i++) PP[i] = 0; /* input file name */ sprintf( cmd, "\0"); sprintf( string, "swath2grid -kk=CC -oty=UINT16 -off=RB_FMT -if=%s\0" ,file_name); strcat( cmd, string ); /* figure out where to put output file */ dummyFile = (char *)malloc( sizeof(char)*80 ); sprintf( dummyFile, "SWGtarget_xx\0"); of_path = (char *)Mcpathname(dummyFile); (void *)sprintf(trace_string,"%s OutputPath=%s",server,of_path); M0sxtrce( trace_string ); /* 1000m file names */ if( MODIS_1KM_flag == 1 ) { /* Output Pixel Size */ temp_res = 1.00; temp_mag = (float)request_line_magnification; if( temp_mag < 0.0 ) temp_mag = 1.0; pixelSize = temp_mag * 1000; sprintf( string, " -opsz=%d\0", pixelSize); strcat( cmd, string ); /* add the geo file name */ geo_name = (char *)malloc( sizeof(char)*80 ); sprintf( geo_string, ".geo.\0"); rc = M0insertstring( file_name, ".1000m.", geo_string, &geo_name ); sprintf( string, " -gf=%s\0" ,geo_name); strcat( cmd, string ); /* add the target file name */ of_name = (char *)malloc( sizeof(char)*80 ); sprintf( of_string, ".1000m\0"); rc = M0insertstring( dummyFile, "_xx", of_string, &of_name ); sprintf( string, " -of=%s\0" ,of_name); strcat( cmd, string ); of_dat = (char *)malloc( sizeof(char)*80 ); sprintf( of_dat, "%s\0", of_name); /* 500m file names */ } else if( MODIS_HKM_flag == 1 ) { /* Output Pixel Size */ temp_res = 0.50; temp_mag = (float)request_line_magnification; if( temp_mag < 0.0 ) temp_mag = 1.0; pixelSize = temp_mag * 500; sprintf( string, " -opsz=%d\0", pixelSize); strcat( cmd, string ); /* add the geo file name */ geo_name = (char *)malloc( sizeof(char)*80 ); sprintf( geo_string, ".geo.\0"); rc = M0insertstring( file_name, ".500m.", geo_string, &geo_name ); sprintf( string, " -gf=%s\0" ,geo_name); strcat( cmd, string ); /* add the target file name */ of_name = (char *)malloc( sizeof(char)*80 ); sprintf( of_string, ".500m\0"); rc = M0insertstring( dummyFile, "_xx", of_string, &of_name ); sprintf( string, " -of=%s\0" ,of_name); strcat( cmd, string ); of_dat = (char *)malloc( sizeof(char)*80 ); sprintf( of_dat, "%s\0", of_name); /* 250m file names */ } else if( MODIS_QKM_flag == 1 ) { /* Output Pixel Size */ temp_res = 0.25; temp_mag = (float)request_line_magnification; if( temp_mag < 0.0 ) temp_mag = 1.0; pixelSize = temp_mag * 250; sprintf( string, " -opsz=%d\0", pixelSize); strcat( cmd, string ); /* add the geo file name */ geo_name = (char *)malloc( sizeof(char)*80 ); sprintf( geo_string, ".geo.\0"); rc = M0insertstring( file_name, ".250m.", geo_string, &geo_name ); sprintf( string, " -gf=%s\0" ,geo_name); strcat( cmd, string ); /* add the target file name */ of_name = (char *)malloc( sizeof(char)*80 ); sprintf( of_string, ".250m\0"); rc = M0insertstring( dummyFile, "_xx", of_string, &of_name ); sprintf( string, " -of=%s\0" ,of_name); strcat( cmd, string ); of_dat = (char *)malloc( sizeof(char)*80 ); sprintf( of_dat, "%s\0", of_name); } /* add the output projection and the associated parameter file */ /* MERCATOR projection */ if( strncmp(navproj,"MERC",4) == 0 ) { /* append projection sphere and name */ sprintf( string, " -oproj=MERCAT -osp=8\0"); strcat( cmd, string ); /* Projection Parameters */ CentMer = request_center_longitude; TrueScale = 0.0; /* construct the Projection parameter string */ sprintf( string, " -oprm=%d,%d,%d,%d,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d\0", SMajor, SMinor, PP[3], PP[4], CentMer, TrueScale, PP[7], PP[8], PP[9], PP[10], PP[11], PP[12], PP[13], PP[14], PP[15] ); strcat( cmd, string ); /* North/South pole for navgation */ navpole = stralloc( "NORTH", NULL); /* array for navigation transform intialization */ navparm[0] = 10000.0; navparm[1] = 10000.0; navparm[2] = TrueScale; navparm[3] = -1.0 * CentMer; navparm[4] = temp_mag * temp_res; /* LAMBERT CONFORMAL projection */ } else if( strncmp(navproj,"LAMB",4) == 0 ) { /* append projection sphere and name */ sprintf( string, " -oproj=LAMCC -osp=8\0"); strcat( cmd, string ); /* Projection Parameters */ StdPr1 = request_center_latitude - (10*temp_mag); StdPr2 = request_center_latitude + (10*temp_mag); CentMer = request_center_longitude; OriginLat = request_center_latitude; /* construct the Projection parameter string */ sprintf( string, " -oprm=%d,%d,%f,%f,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d\0", SMajor, SMinor, StdPr1, StdPr2, CentMer, OriginLat, PP[7], PP[8], PP[9], PP[10], PP[11], PP[12], PP[13], PP[14], PP[15] ); strcat( cmd, string ); /* North/South pole for navgation */ navpole = stralloc( "NORTH", NULL); /* array for navigation transform intialization */ navparm[0] = 1.0; navparm[1] = 10000.0; navparm[2] = StdPr1; navparm[3] = StdPr2; navparm[4] = temp_mag * temp_res; navparm[5] = -1.0 * CentMer; /* RECTILINEAR projection */ } else if( strncmp(navproj,"RECT",4) == 0 ) { /* append projection sphere and name */ /* sprintf( string, " -oproj=LAMCC -osp=8\0"); */ sprintf( string, " -oproj=EQRECT -osp=8\0"); strcat( cmd, string ); /* Projection Parameters */ if( request_lalo_flag == FALSE ) { CentMer = image_geo_center_longitude; }else{ CentMer = request_center_longitude; } /* construct the Projection parameter string */ sprintf( string, " -oprm=%d,%d,%f,%f,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d\0", PP[1], PP[2], PP[3], PP[4], CentMer, PP[6], PP[7], PP[8], PP[9], PP[10], PP[11], PP[12], PP[13], PP[14], PP[15] ); strcat( cmd, string ); /* North/South pole for navgation */ navpole = stralloc( "NORTH", NULL); /* array for navigation transform initialization */ navparm[0] = 10000.0; navparm[1] = image_geo_center_latitude; navparm[2] = 10000.0; navparm[3] = -1 * image_geo_center_longitude; navparm[4] = (temp_mag * temp_res)/111.0; navparm[5] = (temp_mag * temp_res)/111.0; /* POLAR STEROGRAPHIC peojection */ } else if( strncmp(navproj,"PS",2) == 0 ) { /* append projection sphere and name */ sprintf( string, " -oproj=PS -osp=8\0"); strcat( cmd, string ); /* Projection Parameters */ LongPol = request_center_longitude; TrueScale = request_center_latitude; /* construct the Projection parameter string */ sprintf( string, " -oprm=%d,%d,%d,%d,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d\0", SMajor, SMinor, PP[3], PP[4], LongPol, TrueScale, PP[7], PP[8], PP[9], PP[10], PP[11], PP[12], PP[13], PP[14], PP[15] ); strcat( cmd, string ); /* North/South pole for navgation */ navpole = stralloc( "NORTH", NULL); /* array for navigation transform intialization */ navparm[0] = 1.0; navparm[1] = 10000.0; navparm[2] = request_center_latitude; navparm[3] = temp_mag * temp_res; navparm[4] = -1.0 * request_center_longitude; /* Invalid projection */ } else { (void)strcpy(requestBlock.errormsg, "The requested projection is not supported"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } /* generate a navigation */ rc = m0GenNavBlk( navproj, navpole, &navparm, &nav_block ); if( rc != 0 ) { (void)strcpy(requestBlock.errormsg, "Failed to generate specified navigation type"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } /* initialize the navigation */ rc = nvprep_( &ONE, nav_block ); if( rc != 0 ) { (void)strcpy(requestBlock.errormsg, "Failed to initialize navigation Part 1"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } memcpy(&LL, llchar, sizeof(llchar)); rc = nv1ini_( &TWO, &LL ); if (rc != 0) { (void)strcpy(requestBlock.errormsg, "Failed to initialize navigation Part 2"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } /* convert lat/lon to satellite line/elem */ if( request_lalo_flag == TRUE ) { Flat = request_center_latitude; Flon = -1* request_center_longitude; (void *)sprintf(trace_string,"%s Center: Lat=%f Lon=%f",server,Flat,Flon); M0sxtrce( trace_string ); rc = nv1eas_(&Flat,&Flon,&dummy,&Fline,&Felem,&dummy); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Specified Lat/Lon not in image\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } Fline_UL = Fline - (request_line_size/2); Felem_UL = Felem - (request_element_size/2); (void *)sprintf(trace_string,"%s ECenter Line=%f Elem=%f",server,Fline_UL,Felem_UL); M0sxtrce( trace_string ); } else { /* Use MAX/MIN lat/lons from GEO file */ Flat = image_geo_maximum_latitude; Flon = -1 * image_geo_minimum_longitude; (void *)sprintf(trace_string,"%s Upper: Lat=%f Lon=%f",server,Flat,Flon); M0sxtrce( trace_string ); rc = nv1eas_(&Flat,&Flon,&dummy,&Fline,&Felem,&dummy); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Specified Lat/Lon not in image\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } Fline_UL = Fline; Felem_UL = Felem; (void *)sprintf(trace_string,"%s EUpper Line=%f Elem=%f",server,Fline_UL,Felem_UL); M0sxtrce( trace_string ); /* LR Lat/lon */ Flat = image_geo_minimum_latitude; Flon = -1 * image_geo_maximum_longitude; (void *)sprintf(trace_string,"%s Lower: Lat=%f Lon=%f",server,Flat,Flon); M0sxtrce( trace_string ); rc = nv1eas_(&Flat,&Flon,&dummy,&Fline,&Felem,&dummy); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Specified Lat/Lon not in image\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } Fline_LR = Fline; Felem_LR = Felem; (void *)sprintf(trace_string,"%s ELower Line=%f Elem=%f",server,Fline_LR,Felem_LR); M0sxtrce( trace_string ); } /* compute the UL corner Lat/Lon */ rc = nv1sae_(&Fline_UL,&Felem_UL,&dummy,&Flat_UL,&Flon_UL,&dummy); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Specified Lat/Lon not in image\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } Flon_UL = -1*Flon_UL; (void *)sprintf(trace_string,"%s COMPUTED UL Lat=%f Lon=%f",server,Flat_UL,Flon_UL); M0sxtrce( trace_string ); /* compute the LR corner Lat/Lon */ if( REQUEST_SIZE_FLAG == 0 ) { Fline_LR = Fline_UL + request_line_size; Felem_LR = Felem_UL + request_element_size; } (void *)sprintf(trace_string,"%s COMPUTED LR line=%f elem=%f",server,Fline_LR,Felem_LR); M0sxtrce( trace_string ); rc = nv1sae_(&Fline_LR,&Felem_LR,&dummy,&Flat_LR,&Flon_LR,&dummy); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Specified Lat/Lon not in image\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } Flon_LR = -1*Flon_LR; (void *)sprintf(trace_string,"%s COMPUTED LR Lat=%f Lon=%f",server,Flat_LR,Flon_LR); M0sxtrce( trace_string ); /* append the UL and LR output corners */ sprintf( string, " -oul=%f,%f\0",Flon_UL,Flat_UL); strcat( cmd, string ); sprintf( string, " -olr=%f,%f\0",Flon_LR,Flat_LR); strcat( cmd, string ); /* new starting line and element */ request_starting_line = Fline_UL; request_starting_element = Felem_UL; request_line_resolution = 1; request_element_resolution = 1; /* start SDS list based on requested bands */ sprintf( string, " -sds=\0"); strcat( cmd, string ); /* if necessary, add EV_Band26 band */ if( EVBAND26 == 1 && ev_band26 == 1 ) { sprintf( string, "EV_Band26\0"); strcat( cmd, string ); found = 0; for( i=0; i xx \0"); strcat( cmd, string ); /* print the predicted name of the .dat file */ (void *)sprintf(trace_string,"%s .DAT=%s",server,of_dat); M0sxtrce( trace_string ); /* lock the .dat file */ lock_( of_dat, (FsLen)strlen(of_dat) ); /* create the header file name */ of_hdr = (char *)malloc( sizeof(char)*80 ); sprintf( of_hdr, "%s\0", of_dat); sprintf( hdr_string, ".hdr\0"); rc = M0insertstring( of_hdr, ".dat", hdr_string, &of_hdr ); (void *)sprintf(trace_string,"%s .HDR=%s",server,of_hdr); M0sxtrce( trace_string ); /* fork and execute command */ (void *)sprintf(trace_string,"%s CMD = %s",server, cmd ); M0sxtrce( trace_string ); rc = system( cmd ); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Failed execution of swath2grid\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } (void *)sprintf(trace_string,"%s system=%s",server,rc); M0sxtrce( trace_string ); /* scrap temp strings */ free( geo_name ); free( of_name ); /* read the .hdr file to get the number of lines and elements */ rc = STG_readhdr( of_hdr, &STG_parms ); if( REQUEST_SIZE_FLAG == 1 ) { /* size of the image created by MRTSwath */ request_line_size = (int)STG_parms[0]; request_element_size = (int)STG_parms[1]/4*4; /* number of degrees of Lat/Lon in the image created by MRTSWath */ Latitude_diff = Flat_UL-Flat_LR; if( Latitude_diff < 0.0 ) Latitude_diff = -1.0*Latitude_diff; Longitude_diff = Flon_UL-Flon_LR; if( Longitude_diff < 0.0 ) Longitude_diff = -1.0*Longitude_diff; /* degrees per Line/Element in the image created by MRTSwath */ DPL = Latitude_diff / STG_parms[0]; DPE = Longitude_diff / STG_parms[1]; /* array for navigation transform initialization */ navparm[0] = 1.0; navparm[1] = Flat_UL; navparm[2] = 1.0; navparm[3] = -1 * Flon_UL; navparm[4] = DPL; navparm[5] = DPE; /* generate a navigation for the image returned by MRTSwath */ rc = m0GenNavBlk( navproj, navpole, &navparm, &nav_block ); if( rc != 0 ) { (void)strcpy(requestBlock.errormsg, "Failed to generate RECT projection"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } /* set starting line/element to 1/1 */ request_starting_line = 1; request_starting_element = 1; } image_line_size = STG_parms[0]; image_element_size = STG_parms[1]; /* resolution reduction has been done by SwathToGrid - set internals to 1 */ lineSampleRate = 1; elemSampleRate = 1; /* convert output lat/lon to satellite line/elem */ Flat = (float)STG_parms[2] * .000001; Flon = (float)STG_parms[3] * -.000001;; (void *)sprintf(trace_string,"%s Output Lat=%f Lon=%f",server,Flat,Flon); M0sxtrce( trace_string ); rc = nv1eas_(&Flat,&Flon,&dummy,&Fline,&Felem,&dummy); if (rc < 0) { (void)strcpy(requestBlock.errormsg, "Specified Lat/Lon not in image\n"); requestBlock.returncode = -11001; M0sxdone(&requestBlock); return(0); } (void *)sprintf(trace_string,"%s Input Line=%f Elem=%f",server,Fline_UL,Felem_UL); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s Output Line=%f Elem=%f",server,Fline,Felem); M0sxtrce( trace_string ); /* set image read bounds to match new image */ read_starting_line = (int) (Fline_UL-Fline); read_starting_element = (int) (Felem_UL-Felem); if( read_starting_line < 0 ) read_starting_line = 1; if( read_starting_element < 0 ) read_starting_element = 1; read_ending_line = read_starting_line + request_line_size-1; read_ending_element = read_starting_element + request_element_size-1; read_line_size = request_line_size; read_element_size = request_element_size; /* set the flag indicating data is in binary file */ swath2grid_flag = 1; } /* *************************** Transfer starts here ***************************** */ (void *)sprintf(trace_string,"%s TRANSFER",server); M0sxtrce( trace_string ); if( swath2grid_flag == 0 ) { /* size of a lat/lon transfer array */ lalo_array_line_size = (read_geo_line_size / image_geo_line_magnification) +2; if ( lalo_array_line_size <= 1 ) lalo_array_line_size = 2; lalo_array_elem_size = (read_geo_element_size / image_geo_element_magnification) +2; if ( lalo_array_elem_size <= 1 ) lalo_array_elem_size = 2; lalo_array_size = lalo_array_line_size * lalo_array_elem_size * image_geo_data_size; (void *)sprintf(trace_string,"%s lalo_array_size=%d",server,lalo_array_size); M0sxtrce( trace_string ); /* size of the AUX block */ aux_block_size = (MODIS_LAT_AUX + lalo_array_size ) + (MODIS_LON_AUX + lalo_array_size ); } else { /* image_line_size = request_line_size; */ /* image_element_size = request_element_size; */ lalo_array_line_size = 0; lalo_array_elem_size = 0; lalo_array_size = 0; aux_block_size = 0; MODIS_AUX_ENTRIES = 0; } (void *)sprintf(trace_string,"%s aux_block_size=%d",server,aux_block_size); M0sxtrce( trace_string ); /* size of the line prefix */ if( request_n_bands == 1 ) { psize = 0; } else { psize = request_n_bands / 4; if( (request_n_bands % 4) != 0 ) psize = psize+1; psize = psize * 4; } /* size of the DAT block */ dat_block_size = (read_line_size / request_line_magnification) * ( (read_element_size / request_element_magnification) * request_n_bands * request_data_size + psize ); (void *)sprintf(trace_string,"%s dat_block_size=%d",server,dat_block_size); M0sxtrce( trace_string ); /* send the size of the total transmission */ totalSize = (DIR_SIZE*4) + (NAV_BLOCK_SIZE*4) + (CAL_BLOCK_SIZE*4) + (aux_block_size) + (dat_block_size); (void *)sprintf(trace_string,"%s total_block_size=%d",server,totalSize); M0sxtrce( trace_string ); requestBlock.reply_length += totalSize; M0swbyt4(&totalSize, 1); rc = M0sxsend(4, &totalSize ); /* ***************** DIRECTORY BLOCK ****************** */ /* initialize the directory block */ for( i=0; i 1 ) { directory[14] = psize; directory[50] = psize; for( i=0; i=0 && i=0 && j sector_max_lat ) sector_max_lat = Latitude_array[k]; } if( Longitude_array[k] != -999.0 ) { if( Longitude_array[k] < sector_min_lon ) sector_min_lon = Longitude_array[k]; if( Longitude_array[k] > sector_max_lon ) sector_max_lon = Longitude_array[k]; } } } } if( swath2grid_flag == 0 ) { /* initialize the navigation block */ for( i=0; i70 ) { sprintf(trace_string, " NAV BLOCK: nav_block[%d]=%d", i, nav_block[i]); M0sxtrce( trace_string ); } } } /* send the navigation */ if( swath2grid_flag == 0 ) { M0swbyt4( &nav_block[2], NAV_BLOCK_SIZE-2 ); } else { M0swbyt4( &nav_block[1], NAV_BLOCK_SIZE-1 ); } rc = M0sxsend( NAV_BLOCK_SIZE*4, nav_block ); sprintf(trace_string, "%s sent navigation: bytes=%d", server,NAV_BLOCK_SIZE*4); M0sxtrce( trace_string ); /* ***************** NAVIGATION BLOCK ***************** */ /* **************** CALIBRATION BLOCK ***************** */ if( CAL_BLOCK_SIZE > 0 ) { /* initialize the calibration block */ for( i=0; i 0 ) { float_array = malloc( lalo_array_size ); if( float_array == NULL ) { (void)strcpy(requestBlock.errormsg, "Failed malloc of lat/lon line array"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* LATITUDE entry */ aux_head[0] = AUX_MAGIC_NUMBER; aux_head[1] = MODIS_LAT_AUX + lalo_array_size; aux_head[2] = 8; aux_head[3] = lalo_array_size; memcpy( (void *)&aux_head[4], (void *)"LATITUDE", 8); M0swbyt4( aux_head, 6); rc = M0sxsend( 24, aux_head ); /* allow for line magnification */ if( read_geo_starting_line == 0 ) { starting_line = read_geo_starting_line; } else { starting_line = (read_geo_starting_line/image_geo_line_magnification)*image_geo_line_magnification; if( starting_line != read_geo_starting_line ) { starting_line=((read_geo_starting_line/image_geo_line_magnification)+1)*image_geo_line_magnification; } } ending_line = starting_line + ( (lalo_array_line_size-1) * image_geo_line_magnification ); /* allow for element magnification */ if( read_geo_starting_element == 0 ) { starting_elem = read_geo_starting_element; } else { starting_elem = (read_geo_starting_element/image_geo_element_magnification)*image_geo_element_magnification; if( starting_elem != read_geo_starting_element ) { starting_elem=((read_geo_starting_element/image_geo_element_magnification)+1)*image_geo_element_magnification; } } ending_elem = starting_elem + ( (lalo_array_elem_size-1) * image_geo_element_magnification ); sprintf(trace_string, "%s LAT: LINE start=%d end=%d mag=%d", server, starting_line, ending_line, image_geo_line_magnification); M0sxtrce( trace_string ); sprintf(trace_string, "%s LAT: ELEM start=%d end=%d mag=%d", server, starting_elem, ending_elem, image_geo_element_magnification); M0sxtrce( trace_string ); sprintf(trace_string, "%s LAT: SIZE line=%d elem=%d", server, image_geo_line_size, image_geo_element_size); M0sxtrce( trace_string ); sprintf(trace_string, "%s LALO: line=%d elem=%d size=%d", server, lalo_array_line_size, lalo_array_elem_size, lalo_array_size); M0sxtrce( trace_string ); /* sample down the Latitude array */ jj = 0; bad_Latitudes = 0; nbad = 0; for ( i=starting_line; i<=ending_line; i=i+image_geo_line_magnification){ for ( j=starting_elem; j<=ending_elem; j=j+image_geo_element_magnification){ if( (i>=0 && i=0 && j=0 && i=0 && j 1 ) { memcpy( (void *)&uchar_array[0], (void *)&level_map[0], psize ); } } else if( space == 2 ) { ushort_array=malloc(((psize/2)+(request_n_bands*request_element_size))*sizeof(unsigned short int)); if( ushort_array == NULL ) { if( swath2grid_flag == 1 ) { lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_dat) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } (void)strcpy(requestBlock.errormsg, "Failed malloc of line array"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { memcpy( (void *)&ushort_array[0], (void *)&level_map[0], psize ); } } else if( space == 4 ) { ulong_array=malloc(((psize/4)+(request_n_bands*request_element_size))*sizeof(unsigned int)); if( ulong_array == NULL ) { if( swath2grid_flag == 1 ) { lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_dat) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } (void)strcpy(requestBlock.errormsg, "Failed malloc of line array"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_n_bands > 1 ) { memcpy( (void *)&ulong_array[0], (void *)&level_map[0], psize ); } } sprintf(trace_string, "%s Past input array malloc", server); M0sxtrce( trace_string ); /* aquire memory to hold 1 image data */ if( singleband_flag == TRUE ) { Data_array = malloc( image_line_size * image_element_size * sizeof(uint16)); sprintf(trace_string, "%s lineSize=%d elemSize=%d ", server, image_line_size, image_element_size); M0sxtrce( trace_string ); } else { Data_array = malloc( image_element_size * sizeof(uint16)); } if( Data_array == NULL ) { if( swath2grid_flag == 1 ) { lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_dat) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } (void)strcpy(requestBlock.errormsg, "Failed malloc of data"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } sprintf(trace_string, "%s Past output array malloc", server); M0sxtrce( trace_string ); /* if compressed data --> read the entire image */ if( swath2grid_flag == 1 ) { i = image_line_size * image_element_size * sizeof(uint16); status = Mcread( of_dat, (off_t)0, (size_t)i, (void *)Data_array); if( status < 0 ) { if( swath2grid_flag == 1 ) { lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_dat) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } (void)strcpy(requestBlock.errormsg, "Failed read of swath2grid data"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } sprintf(trace_string, "%s Past output array read", server); M0sxtrce( trace_string ); /* read_starting_line = 1; read_ending_line = image_line_size; read_starting_element = 1; read_ending_element = image_element_size; */ } else { if( singleband_flag == TRUE ) { sds_id = SDselect( sd_id, sd_data_index[0] ); status = SDgetinfo( sds_id, name, &sds_rank, sds_dim_sizes, &sds_data_type, &sds_n_attrs ); if( status == FAIL ) { if( swath2grid_flag == 1 ) { lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_dat) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } sprintf(trace_string, "%s GETINFO FAILED for %s", server, name); M0sxtrce( trace_string ); return 0; } if( sds_rank == 2 ) { start[0] = 0; start[1] = 0; stride[0] = 1; stride[1] = 1; edge[0] = image_line_size; edge[1] = image_element_size; } else { start[0] = sd_band_index[0]; start[1] = 0; start[2] = 0; stride[0] = sd_band_num[0]; stride[1] = 1; stride[2] = 1; edge[0] = 1; edge[1] = image_line_size; edge[2] = image_element_size; } status = SDreaddata( sds_id, start, stride, edge, Data_array); if( status == FAIL ) { if( swath2grid_flag == 1 ) { lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_dat) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } (void)strcpy(requestBlock.errormsg, "Failed read of data"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return (0); } } } sprintf(trace_string, "%s READ LINE: START=%d END=%d", server, read_starting_line, read_ending_line); M0sxtrce( trace_string ); sprintf(trace_string, "%s READ ELEM: START=%d END=%d", server, read_starting_element, read_ending_element); M0sxtrce( trace_string ); /* LOOP through the data field */ for( i=read_starting_line; i<=read_ending_line; i=i+lineSampleRate ) { /* LOOP through the bands to build the McIDAS data array */ for( band_ptr=0; band_ptr read data line by line */ if( singleband_flag == FALSE ) { /* open the SDS */ sds_id = SDselect( sd_id, sd_data_index[band_ptr] ); /* get the attributes for this SDS */ status = SDgetinfo( sds_id, name, &sds_rank, sds_dim_sizes, &sds_data_type, &sds_n_attrs ); if( status == FAIL ) { sprintf(trace_string, "%s GETINFO FAILED for %s", server, name); M0sxtrce( trace_string ); break; } if( i>=0 && i=0 && i=0 && j compute 2D index */ if( singleband_flag == TRUE ) { j = (i*image_element_size) + ie; } switch (ounit_flag) { /* RAW --> RAW */ case 0: raw = (float)Data_array[j] * MODIS_RAW_SCALE; value = (int)raw; if( value == 65535 ) { if( band <= 19 || band == 26 ) value = 0; } break; /* RAW --> REF */ case 1: ref = ( (float)Data_array[j] - reflectance_offsets[band-1]) * reflectance_scales[band-1]; ref = ref * MODIS_REF_SCALE; value = (int)ref; if( value == 65535 ) { if( band <= 19 || band == 26 ) value = 0; } break; /* RAW --> RERA*/ case 6: rera = ( (float)Data_array[j] - radiance_offsets[band-1]) * radiance_scales[band-1]; rera = rera * MODIS_RERA_SCALE; value = (int)rera; if( value == 65535 ) { if( band <= 19 || band == 26 ) value = 0; } break; /* RAW --> RAD */ case 2: rad = ( (float)Data_array[j] - radiance_offsets[band-1]) * radiance_scales[band-1]; temp = MODISbright( rad, band, 1, image_satellite_number ); radn = MODISplanck( temp, band, 0, image_satellite_number ); radn = radn * MODIS_RAD_SCALE; value = (int)radn; break; /* RAW --> RADN */ case 5: rad = ( (float)Data_array[j] - radiance_offsets[band-1]) * radiance_scales[band-1]; rad = rad * MODIS_RAD_SCALE; value = (int)rad; break; /* RAW --> TEMP */ case 3: rad = ( (float)Data_array[j] - radiance_offsets[band-1]) * radiance_scales[band-1]; temp = MODISbright( rad, band, 1, image_satellite_number ); temp = temp * MODIS_TEMP_SCALE; value = (int)temp; break; /* RAW --> BRIT */ case 4: if( request_band_type[band_ptr] == 0 ) { ref = ( (float)Data_array[j] - reflectance_offsets[band-1]) * reflectance_scales[band-1]; if( ref < 0.0 ) { brit = 0.0; } else { ref = ref * 100.; rc = m0grayscale_("ALB", &ref, &rbrit, 3); brit = (rbrit + 0.5) * MODIS_BRIT_SCALE; } } else { rad = ( (float)Data_array[j] - radiance_offsets[band-1]) * radiance_scales[band-1]; temp = MODISbright( rad, band, 1, image_satellite_number); brit = TEMPtoBRIT( band, temp ); brit = (brit + 0.5) * MODIS_BRIT_SCALE; } value = (int)brit; if( value < 0 ) value = 0; if( value > 255 ) value = 255; /* removed for INQ 15401 --- RCD if( value >= 255 ) { value = 255; if( band <= 19 || band == 26 ) value = 0; } */ break; /* RAW --> CNTS */ case 7: cnts = ( (float)Data_array[j] - corrected_counts_offsets[band-1]) * corrected_counts_scales[band-1]; value = (int)cnts; break; } } /* WRITE the McIDAS data array */ if( space == 1 ) { uchar_array[jj] = (unsigned char)value; } else if( space == 2 ) { ushort_array[jj] = (unsigned short)value; } else if( space == 4 ) { ulong_array[jj] = value; } jj = jj+request_n_bands; } /* end access to the SDS */ if( swath2grid_flag == 0 ) status = SDendaccess( sds_id ); } /* correct byte order */ if( space == 4 ) { size = request_n_bands*request_element_size; M0swbyt4( ulong_array+(psize/4), size ); size = size + (psize/4); } if( space == 2 ) { size = request_n_bands*request_element_size; (void)swbyt2_( ushort_array+(psize/2), &size ); size = size + (psize/2); } if( space == 1 ) { size = psize + (request_n_bands*request_element_size); } /* send out the line array */ if( space == 1 ) { rc = M0sxsend( size, uchar_array ); } else if( space == 2 ) { rc = M0sxsend( size*2, ushort_array ); } else if( space == 4 ) { rc = M0sxsend( size*4, ulong_array ); } } /* end HDF access */ if( swath2grid_flag == 0 ) status = SDend( sd_id ); /* unlock .dat file */ if( swath2grid_flag == 1 ) { sprintf(trace_string, "OF_FILE=%s ", of_dat); M0sxtrce( trace_string ); lwd_( of_dat, (FsLen)strlen(of_dat) ); lwd_( of_hdr, (FsLen)strlen(of_hdr) ); unlock_( of_dat, (FsLen)strlen(of_dat) ); lwmop_(); } /* FREE the HDF-EOS array */ free( Data_array ); if( space == 1 ) free ( uchar_array) ; if( space == 2 ) free ( ushort_array ); if( space == 4 ) free ( ulong_array ); /* ******************* DATA BLOCK ********************* */ sprintf(trace_string, "%s Done...", server); M0sxtrce( trace_string ); /* *************************** Transfer ends here ***************************** */ /* LABEL for exit due to error */ SWATH_END_LABEL: sprintf(trace_string, "ABORT -- Something went wrong"); M0sxtrce( trace_string ); /* *************************** MODIS HDF-EOS FILE LOOP **************************** */ /* terminate the request */ M0sxdone(&requestBlock); return (0); } int TEMPtoBRIT( int band, float temp ) { int brit; int rc; float rbrit; rc = m0grayscale_("TEMP", &temp, &rbrit, 4); brit = (int) (rbrit + 0.5); if( brit > 255 ) brit = 255; if( brit < 0 ) brit = 0; return (brit); } float MODISbright( float rad, int band, int units, int satellite ) /* ----------------------------------------------------------------------- */ /* !Description: */ /* Compute brightness temperature for an EOS-AM MODIS infrared band. */ /* Spectral responses for each IR detector were obtained from MCST: */ /* ftp://mcstftp.gsfc.nasa.gov/incoming/MCST/PFM_L1B_LUT_4-30-99 */ /* An average spectral response for each infrared band was */ /* computed. The band-averaged spectral response data were used */ /* to compute the effective central wavenumbers and temperature */ /* correction coefficients included in this module. */ /* !Input Parameters: */ /* RAD Planck radiance (units are determined by UNITS) */ /* BAND MODIS IR band number (20-25, 27-36) */ /* UNITS Flag defining radiance units */ /* 0 => milliWatts per square meter per steradian per */ /* inverse centimeter */ /* 1 => Watts per square meter per steradian per micron */ /* SATELLITE SSEC satellite number */ /* !Output Parameters: */ /* MODIS_BRIGHT Brightness temperature (Kelvin) */ /* Note that a value of -1.0 is returned if */ /* RAD .LE. 0.0, or BAND is not in range 20-25, 27-36. */ /* !Revision History: */ /* Liam.Gumley@ssec.wisc.edu */ /* $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ */ /* !Team-Unique Header: */ /* Developed by the MODIS Group, CIMSS/SSEC, UW-Madison. */ /* Converted to C by the McIDAS SSEC Group, UW-Madison. */ /* ----------------------------------------------------------------------- */ { /* ----------------------------------------------------------------------- */ /* BAND-AVERAGED MODIS SPECTRAL RESPONSE FUNCTIONS FOR TERRA */ /* TEMPERATURE RANGE FOR FIT WAS 180.00 K TO 320.00 K */ /* BANDS */ /* 20, 21, 22, 23, */ /* 24, 25, 26, 27, */ /* 28, 29, 30, 31, */ /* 32, 33, 34, 35, */ /* 36 */ /* NOTE THAT BAND 26 VALUES ARE SET TO ZERO */ /* TERRA satellite */ int satellite_terra = { 101 }; /* Effective central wavenumber (inverse centimeters) */ float cwn_terra[17] = { 2.641775E+03, 2.505277E+03, 2.518028E+03, 2.465428E+03, 2.235815E+03, 2.200346E+03, 0.0, 1.477967E+03, 1.362737E+03, 1.173190E+03, 1.027715E+03, 9.080884E+02, 8.315399E+02, 7.483394E+02, 7.308963E+02, 7.188681E+02, 7.045367E+02 }; /* Temperature correction slope (no units) */ float tcs_terra[17] = { 9.993411E-01, 9.998646E-01, 9.998584E-01, 9.998682E-01, 9.998819E-01, 9.998845E-01, 0.0, 9.994877E-01, 9.994918E-01, 9.995495E-01, 9.997398E-01, 9.995608E-01, 9.997256E-01, 9.999160E-01, 9.999167E-01, 9.999191E-01, 9.999281E-01 }; /* Temperature correction intercept (Kelvin) */ float tci_terra[17] = { 4.770532E-01, 9.262664E-02, 9.757996E-02, 8.929242E-02, 7.310901E-02, 7.060415E-02, 0.0, 2.204921E-01, 2.046087E-01, 1.599191E-01, 8.253401E-02, 1.302699E-01, 7.181833E-02, 1.972608E-02, 1.913568E-02, 1.817817E-02, 1.583042E-02 }; /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ /* BAND-AVERAGED MODIS SPECTRAL RESPONSE FUNCTIONS FOR AQUA */ /* TEMPERATURE RANGE FOR FIT WAS 180.00 K TO 320.00 K */ /* BANDS */ /* 20, 21, 22, 23, */ /* 24, 25, 26, 27, */ /* 28, 29, 30, 31, */ /* 32, 33, 34, 35, */ /* 36 */ /* NOTE THAT BAND 26 VALUES ARE SET TO ZERO */ /* AQUA satellite */ int satellite_aqua = { 111 }; /* Effective central wavenumber (inverse centimeters) */ float cwn_aqua[17] = { 2.647409E+03, 2.511760E+03, 2.517908E+03, 2.462442E+03, 2.248296E+03, 2.209547E+03, 0.0, 1.474262E+03, 1.361626E+03, 1.169626E+03, 1.028740E+03, 9.076813E+02, 8.308411E+02, 7.482978E+02, 7.307766E+02, 7.182094E+02, 7.035007E+02 }; /* Temperature correction slope (no units) */ float tcs_aqua[17] = { 9.993363E-01, 9.998626E-01, 9.998627E-01, 9.998707E-01, 9.998737E-01, 9.998770E-01, 0.0, 9.995694E-01, 9.994867E-01, 9.995270E-01, 9.997382E-01, 9.995270E-01, 9.997271E-01, 9.999173E-01, 9.999070E-01, 9.999198E-01, 9.999233E-01 }; /* Temperature correction intercept (Kelvin) */ float tci_aqua[17] = { 4.818401E-01, 9.426663E-02, 9.458604E-02, 8.736613E-02, 7.873285E-02, 7.550804E-02, 0.0, 1.848769E-01, 2.064384E-01, 1.674982E-01, 8.304364E-02, 1.343433E-01, 7.135051E-02, 1.948513E-02, 2.131043E-02, 1.804156E-02, 1.683156E-02 }; /* ----------------------------------------------------------------------- */ float cwn; float tci; float tcs; float W; float K; float brightness_temp; /* Check input parameters and return if they are bad */ if ( (rad <= 0.0) || (band < 20) || (band > 36) || (band == 26) ) { return -1.0; } /* Get coefficients for Terra or Aqua */ if ( satellite == satellite_terra ) { cwn = cwn_terra[band-20]; tci = tci_terra[band-20]; tcs = tcs_terra[band-20]; } else if( satellite == satellite_aqua ) { cwn = cwn_aqua[band-20]; tci = tci_aqua[band-20]; tcs = tcs_aqua[band-20]; } else { return -1.0; } /* Compute brightness temperature */ if (units == 1) { /* Radiance units are */ /* Watts per square meter per steradian per micron */ W = 1.0E+4 / cwn; K = brightm( W, rad ); } else { /* Radiance units are */ /* milliWatts per square meter per steradian per wavenumber */ K = britem( cwn, rad ); } brightness_temp = (K - tci) / tcs; return brightness_temp; } float brightm( float W, float R ) /* ----------------------------------------------------------------------- */ /* !Description: */ /* Compute brightness temperature given monochromatic Planck radiance. */ /* !Input Parameters: */ /* W Wavelength (microns) */ /* R Planck radiance (Watts per square meter per steradian */ /* per micron) */ /* !Output Parameters: */ /* BRIGHT_M Brightness temperature (Kelvin) */ /* !Revision History: */ /* Liam.Gumley@ssec.wisc.edu */ /* $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ */ /* !Team-Unique Header: */ /* Developed by the MODIS Group, CIMSS/SSEC, UW-Madison. */ /* Converted to C by the McIDAS SSEC Group, UW-Madison. */ /* ----------------------------------------------------------------------- */ /* Constants are from "The Fundamental Physical Constants", */ /* Cohen, E. R. and B. N. Taylor, Physics Today, August 1993. */ { /* Planck constant (Joule second) */ float h = 6.6260755e-34; /* Speed of light in vacuum (meters per second) */ float c = 2.9979246e+8; /* Boltzmann constant (Joules per Kelvin) */ float k = 1.380658e-23; float c1; /* Derived constant */ float c2; /* Derived constant */ float ws; /* Wavelength in meters */ double dvalue; float bright; /* Derive constants */ c1 = 2.0 * h * c * c; c2 = (h * c) / k; /* Check input parameters and return if they are bad */ if ( (W <= 0.0) || (R <= 0.0) ) { return -1; } /* Convert wavelength to meters */ ws = 1.0e-6 * W; /* Compute brightness temperature */ dvalue = c1 / (1.0E+6 * R * pow(ws,5)); bright = c2 / (ws * log(dvalue + 1.0)); return bright; } float britem( float V, float R ) /* ----------------------------------------------------------------------- */ /* !Description: */ /* Compute brightness temperature given monochromatic Planck radiance. */ /* */ /* !Input Parameters: */ /* V Wavenumber (inverse centimeters) */ /* R Planck radiance (milliWatts per square meter per */ /* steradian per inverse centimeter) */ /* */ /* !Output Parameters: */ /* BRIGHT_M Brightness temperature (Kelvin) */ /* */ /* !Revision History: */ /* Liam.Gumley@ssec.wisc.edu */ /* $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ */ /* */ /* !Team-Unique Header: */ /* Developed by the MODIS Group, CIMSS/SSEC, UW-Madison. */ /* Converted to C by the McIDAS SSEC Group, UW-Madison. */ /* */ /* ----------------------------------------------------------------------- */ /* Constants are from "The Fundamental Physical Constants", */ /* Cohen, E. R. and B. N. Taylor, Physics Today, August 1993 */ { /* Planck constant (Joule second) */ float h = 6.6260755e-34; /* Speed of light in vacuum (meters per second) */ float c = 2.9979246e+8; /* Boltzmann constant (Joules per Kelvin) */ float k = 1.380658e-23; /* Derived constants */ float c1; float c2; /* Wavenumber in inverse meters */ float vs; double dvalue; float bright; /* Derive constants */ c1 = 2.0 * h * c * c ; c2 = (h * c) / k; /* Check input parameters and return if they are bad */ if ( (V <= 0.0) || (R <= 0.0) ) { return -1.0; } /* Convert wavenumber to inverse meters */ vs = 1.0e+2 * V; /* Compute brightness temperature */ dvalue = c1 * pow(vs,3) / (1.0E-5 * R) + 1.0; bright = c2 * vs / log(dvalue); return bright; } float MODISplanck( float temp, int band, int units, int satellite ) /* ----------------------------------------------------------------------- */ /* */ /* !DESCRIPTION: */ /* Compute Planck radiance for an EOS-AM MODIS infrared band. */ /* */ /* Spectral responses for each IR detector were obtained from MCST: */ /* ftp://mcstftp.gsfc.nasa.gov/incoming/MCST/PFM_L1B_LUT_4-30-99 */ /* */ /* An average spectral response for each infrared band was */ /* computed. The band-averaged spectral response data were used */ /* to compute the effective central wavenumbers and temperature */ /* correction coefficients included in this module. */ /* */ /* !INPUT PARAMETERS: */ /* TEMP Brightness temperature (Kelvin) */ /* BAND MODIS IR band number (20-25, 27-36) */ /* UNITS Flag defining radiance units */ /* 0 => milliWatts per square meter per steradian per */ /* inverse centimeter */ /* 1 => Watts per square meter per steradian per micron */ /* */ /* !OUTPUT PARAMETERS: */ /* MODIS_PLANCK Planck radiance (units are determined by UNITS) */ /* Note that a value of -1.0 is returned if */ /* TEMP .LE. 0.0, or BAND is not in range 20-25, 27-36. */ /* */ /* !REVISION HISTORY: */ /* Liam.Gumley@ssec.wisc.edu */ /* $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ */ /* */ /* !TEAM-UNIQUE HEADER: */ /* Developed by the MODIS Group, CIMSS/SSEC, UW-Madison. */ /* Converted to C by the McIDAS SSEC Group, UW-Madison. */ /* */ /* ----------------------------------------------------------------------- */ { /* ----------------------------------------------------------------------- */ /* BAND-AVERAGED MODIS SPECTRAL RESPONSE FUNCTIONS FOR TERRAM */ /* TEMPERATURE RANGE FOR FIT WAS 180.00 K TO 320.00 K */ /* BANDS */ /* 20, 21, 22, 23, */ /* 24, 25, 26, 27, */ /* 28, 29, 30, 31, */ /* 32, 33, 34, 35, */ /* 36 */ /* ... NOTE THAT BAND 26 VALUES ARE SET TO ZERO */ /* TERRA Satellite */ int satellite_terra = { 101 }; /* Effective central wavenumber (inverse centimenters) */ float cwn_terra[17] = { 2.641775E+03, 2.505277E+03, 2.518028E+03, 2.465428E+03, 2.235815E+03, 2.200346E+03, 0.0, 1.477967E+03, 1.362737E+03, 1.173190E+03, 1.027715E+03, 9.080884E+02, 8.315399E+02, 7.483394E+02, 7.308963E+02, 7.188681E+02, 7.045367E+02 }; /* Temperature correction slope (no units) */ float tcs_terra[17] = { 9.993411E-01, 9.998646E-01, 9.998584E-01, 9.998682E-01, 9.998819E-01, 9.998845E-01, 0.0, 9.994877E-01, 9.994918E-01, 9.995495E-01, 9.997398E-01, 9.995608E-01, 9.997256E-01, 9.999160E-01, 9.999167E-01, 9.999191E-01, 9.999281E-01 }; /* Temperature correction intercept (Kelvin) */ float tci_terra[17] = { 4.770532E-01, 9.262664E-02, 9.757996E-02, 8.929242E-02, 7.310901E-02, 7.060415E-02, 0.0, 2.204921E-01, 2.046087E-01, 1.599191E-01, 8.253401E-02, 1.302699E-01, 7.181833E-02, 1.972608E-02, 1.913568E-02, 1.817817E-02, 1.583042E-02 }; /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ /* BAND-AVERAGED MODIS SPECTRAL RESPONSE FUNCTIONS FOR AQUA */ /* TEMPERATURE RANGE FOR FIT WAS 180.00 K TO 320.00 K */ /* BANDS */ /* 20, 21, 22, 23, */ /* 24, 25, 26, 27, */ /* 28, 29, 30, 31, */ /* 32, 33, 34, 35, */ /* 36 */ /* NOTE THAT BAND 26 VALUES ARE SET TO ZERO */ /* AQUA satellite */ int satellite_aqua = { 111 }; /* Effective central wavenumber (inverse centimeters) */ float cwn_aqua[17] = { 2.647409E+03, 2.511760E+03, 2.517908E+03, 2.462442E+03, 2.248296E+03, 2.209547E+03, 0.0, 1.474262E+03, 1.361626E+03, 1.169626E+03, 1.028740E+03, 9.076813E+02, 8.308411E+02, 7.482978E+02, 7.307766E+02, 7.182094E+02, 7.035007E+02 }; /* Temperature correction slope (no units) */ float tcs_aqua[17] = { 9.993363E-01, 9.998626E-01, 9.998627E-01, 9.998707E-01, 9.998737E-01, 9.998770E-01, 0.0, 9.995694E-01, 9.994867E-01, 9.995270E-01, 9.997382E-01, 9.995270E-01, 9.997271E-01, 9.999173E-01, 9.999070E-01, 9.999198E-01, 9.999233E-01 }; /* Temperature correction intercept (Kelvin) */ float tci_aqua[17] = { 4.818401E-01, 9.426663E-02, 9.458604E-02, 8.736613E-02, 7.873285E-02, 7.550804E-02, 0.0, 1.848769E-01, 2.064384E-01, 1.674982E-01, 8.304364E-02, 1.343433E-01, 7.135051E-02, 1.948513E-02, 2.131043E-02, 1.804156E-02, 1.683156E-02 }; /* ----------------------------------------------------------------------- */ float cwn; float tci; float tcs; float rad; float V; float W; float T; /* Check input parameters and return if they are bad */ if ( (temp <= 0.0) || (band < 20) || (band > 36) || (band == 26) ) { return -1; } /* Get coefficients for Terra or Aqua */ if ( satellite == satellite_terra ) { cwn = cwn_terra[band-20]; tci = tci_terra[band-20]; tcs = tcs_terra[band-20]; } else if( satellite == satellite_aqua ) { cwn = cwn_aqua[band-20]; tci = tci_aqua[band-20]; tcs = tcs_aqua[band-20]; } else { return -1.0; } /* Compute brightness temperature */ if (units == 1) { /* Radiance units are */ /* Watts per square meter per steradian per micron */ W = 1.0e+4 / cwn; T = temp * tcs; rad = planckm( W, T ) + tci; } else { /* Radiance units are */ /* milliWatts per square meter per steradian per wavenumber */ V = cwn; T = temp * tcs + tci; rad = plancm( V, T ); } return rad; } float planckm( float W, float T ) /* ----------------------------------------------------------------------- */ /* */ /* !DESCRIPTION: */ /* Compute monochromatic Planck radiance given brightness temperature. */ /* */ /* !INPUT PARAMETERS: */ /* W Wavelength (microns) */ /* T Brightness temperature (Kelvin) */ /* */ /* !OUTPUT PARAMETERS: */ /* PLANCK_M Planck radiance (Watts per square meter per steradian */ /* per micron) */ /* */ /* !REVISION HISTORY: */ /* Liam.Gumley@ssec.wisc.edu */ /* $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ */ /* */ /* !TEAM-UNIQUE HEADER: */ /* Developed by the MODIS Group, CIMSS/SSEC, UW-Madison. */ /* Converted to C by the McIDAS SSEC Group, UW-Madison. */ /* */ /* ----------------------------------------------------------------------- */ /* Constants are from "The Fundamental Physical Constants", */ /* Cohen, E. R. and B. N. Taylor, Physics Today, August 1993. */ { /* Planck constant (Joule second) */ float h = 6.6260755E-34; /* Speed of light in vacuum (meters per second) */ float c = 2.9979246E+8; /* Boltzmann constant (Joules per Kelvin) */ float k = 1.380658E-23; /* Wavelength in meters */ float ws; /* Derived constants */ float c1; float c2; float exponential; float power; float radiance; /* derive constants */ c1 = 2.0 * h * c * c; c2 = (h * c) / k; /* Check input parameters and return if they are bad */ if ( (W <= 0.0) || (T <= 0.0) ) { return -1.0; } /* Convert wavelength to meters */ ws = 1.0e-6 * W; /* Compute Planck radiance */ exponential = c2 / (ws * T); power = pow(ws,5); radiance = 1.0E-6 * (c1 / power) / (exp(exponential) - 1.0); return radiance; } float plancm( float V, float T) /* ----------------------------------------------------------------------- */ /* */ /* !DESCRIPTION: */ /* Compute monochromatic Planck radiance given brightness temperature. */ /* */ /* !INPUT PARAMETERS: */ /* V Wavenumber (inverse centimeters) */ /* T Brightness temperature (Kelvin) */ /* */ /* !OUTPUT PARAMETERS: */ /* PLANC_M Planck radiance (milliWatts per square meter per */ /* steradian per inverse centimeter) */ /* */ /* !REVISION HISTORY: */ /* Liam.Gumley@ssec.wisc.edu */ /* $Id: modsaget.c,v 1.62 2019/11/07 15:03:06 russd Tst $ */ /* */ /* !TEAM-UNIQUE HEADER: */ /* Developed by the MODIS Group, CIMSS/SSEC, UW-Madison. */ /* Converted to C by the McIDAS SSEC Group, UW-Madison. */ /* */ /* ----------------------------------------------------------------------- */ /* Constants are from "The Fundamental Physical Constants", */ /* Cohen, E. R. and B. N. Taylor, Physics Today, August 1993. */ { /* Planck constant (Joule second) */ float h = 6.6260755E-34; /* Speed of light in vacuum (meters per second) */ float c = 2.9979246E+8; /* Boltzmann constant (Joules per Kelvin) */ float k = 1.380658E-23; /* Wavenumber in inverse meters */ float vs; /* Derived constants */ float c1; float c2; float exponential; float power; float radiance; /* Derive constants */ c1 = 2.0 * h * c * c; c2 = (h * c) / k; /* Check input parameters and return if they are bad */ if ( (V <= 0.0) || (T <= 0.0) ) { return -1.0; } /* Convert wavenumber to inverse meters */ vs = 1.0E+2 * V; /* Compute Planck radiance */ exponential = c2 * vs / T; power = pow(vs,3); radiance = 1.0E5 * (c1 * power) / (exp(exponential) - 1.0); return radiance; } int STG_readhdr(char *file, Fint *parms ) { char *parm; const char text[2400]; char line[80]; int ok; int ptr; int nchars; int handle; int nparm; int nparms; double dparm; static char trace_string[500]; /* traceing text */ (void *)sprintf(trace_string," STG_readhdr: file=%s",file); M0sxtrce( trace_string ); nchars = 0; nparms = 0; ok = Mcread( file, 0, 2400, &text ); for( ptr=0; ptr<2400; ptr++ ) { ok = iscntrl( text[ptr] ); if( ok > 0 ) { if( nchars > 0 ) { line[nchars] = '\0'; handle = Mcargparse( line, NULL, NULL ); ok = Mcargstr(handle, "NLINES", 2, (char *)NULL, &parm ); if( ok > 0 ) { ok = Mcstrtoint( parm, &nparm); parms[0] = nparm; nparms++; } ok = Mcargstr(handle, "NSAMPLES", 2, (char *)NULL, &parm ); if( ok > 0 ) { ok = Mcstrtoint( parm, &nparm); parms[1]= nparm; nparms++; } ok = Mcargstr(handle, "UL_CORNER_LATLON", 2, (char *)NULL, &parm ); if( ok > 0 ) { ok = Mcstrtodbl( parm, &dparm); nparm = dparm * 1000000.0; parms[2]= nparm; nparms++; } ok = Mcargstr(handle, "UL_CORNER_LATLON", 3, (char *)NULL, &parm ); if( ok > 0 ) { ok = Mcstrtodbl( parm, &dparm); nparm = dparm * 1000000.0; parms[3]= nparm; nparms++; } ok = Mcargstr(handle, "LR_CORNER_LATLON", 2, (char *)NULL, &parm ); if( ok > 0 ) { ok = Mcstrtodbl( parm, &dparm); nparm = dparm * 1000000.0; parms[4]= nparm; nparms++; } ok = Mcargstr(handle, "LR_CORNER_LATLON", 3, (char *)NULL, &parm ); if( ok > 0 ) { ok = Mcstrtodbl( parm, &dparm); nparm = dparm * 1000000.0; parms[5]= nparm; nparms++; } Mcargfree (handle); if( nparms == 6 ) goto GETOUT; } nchars = 0; } else { line[nchars] = text[ptr]; nchars++; } } GETOUT: return(0); }