/* * Copyright(c) 2006, Space Science and Engineering Center, UW-Madison * Refer to "McIDAS Software Acquisition and Distribution Policies" * in the file mcidas/data/license.txt */ /**** $Id: mod3aget.c,v 1.5 2007/10/09 19:26:29 russd Tst $ ****/ /* ** Name: ** mod3aget : ADDE image server for MODIS Geo (MOD03) 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 format of MODIS product data ** ** Categories: ** ADDE server */ #include #include #include #include #include "mcidas.h" #include "mcidasp.h" #include "m0glue.h" #include "m0arg.h" #include "mfhdf.h" #include "hdf.h" #include "modx.h" /* Prototypes */ int GetBits( int, int, int); int MASK_RAWtoRAW( int, int, int ); int MASK_RAWtoBRIT( int, int, int ); int main ( int argc, char *argv[] ) #define TRUE 1 #define FALSE 0 #define DIR_SIZE 64 #define IMAGE_FILE_VERSION 4 #define MAX_STR_LEN 80 #define MAX_BANDS 9 { /* MODIS constants */ int MODIS_NAV_OFFSET = 256; /* NAV block offset */ int MODIS_CAL_OFFSET = 768; /* CAL block offset */ int MODIS_AUX_OFFSET = 1280; /* 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 = 128; /* CAL block word size */ int MODIS_RAW_SCALE = 1; /* scaling for RAW data */ /* variables used: */ const char *dum; /* dummy variable for arg routines */ const char server[]={"MOD3AGET"}; /* server name */ static char trace_string[500]; /* traceing text */ char chhmm[5]; char *def_unit; /* default UNIT */ char *dir_unit; /* directory UNIT */ char *cdate; /* file date chars */ char *chms; /* file time chars */ char *mask; /* dataset file mask */ char *cname; /* file name */ char *cprod; /* product name */ char *group; /* dataset group */ char *place; /* coordinate system */ char *punit; /* parameter UNITS */ char *request; /* request string */ char *unit; /* UNITS keyword */ char **flist = NULL; /* hdf file list */ char *dataset; char *type; char *format; char *info; char *comment; float lat_diff; /* latitude difference */ float lon_diff; /* longitude difference */ float minimum; /* minimum difference */ double raw_min; double raw_max; float rvalue; float minrawval; float maxrawval; int minbritval; int maxbritval; /* attribute values assigned to data sets */ int16 Parm_miss; /* parameter missing data */ float64 Parm_scale; /* parameter scale */ float64 Parm_offset; /* parameter offset */ Fint4 aux_head[100]; /* AUX entry header */ Fint4 directory[DIR_SIZE]; /* image directory block */ Fint4 nav_block[128]; /* navigation block */ Fint4 cal_block[128]; /* calibration block */ int aux_block_size; /* size of the AUX block */ int image_bands[MAX_BANDS]; /* image bands */ int band_ptr; /* band loop pointer */ int read_this_band; /* flag indicates if we want this band */ 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 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 iii; /* secondary line index */ int j; /* loop index */ int jj; /* secondary element index */ int k; /* array index */ int miss; 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 element 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 space; /* output spacing */ int totalSize; /* transfer byte count */ int trace; /* trace flag */ int transaction = 0; /* transaction flag */ int user = 0; /* user id */ int rt_flag; int test; int size; int extend; int pad; unsigned int iexp; /* exponent for pow function */ char name[MAX_NC_NAME]; char level_map[MAX_BANDS]; /* prefix level map */ char *cday; char *file_name; char *image_stype; char *last_stype; intn status; int32 n_datasets; int32 n_file_attrs; int32 index; int32 sd_id; int32 sds_id; int32 sds_data_type; int32 sds_rank; 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 starting_line; int ending_line; int starting_elem; int ending_elem; 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_line_base_resolution; int image_element_base_resolution; int image_dataset_position; int image_satellite_number; int image_line_size; int image_element_size; 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_starting_line; int image_geo_ending_line; int image_geo_ending_element; int image_geo_starting_element; 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; float image_geo_minimum_latitude; float image_geo_maximum_latitude; float image_geo_minimum_longitude; float image_geo_maximum_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; float32 band_mins[MAX_BANDS]; float32 band_maxs[MAX_BANDS]; float32 band_scls[MAX_BANDS]; float32 band_offs[MAX_BANDS]; float32 band_fils[MAX_BANDS]; double request_center_latitude; double request_center_longitude; int request_data_size; int request_n_bands; int request_bands[MAX_BANDS]; int got_band[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 file_name_type; 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 HDF_Band1_flag; int HDF_Band2_flag; int HDF_Band3_flag; int HDF_Band4_flag; int HDF_Band5_flag; int HDF_Band6_flag; int HDF_Band7_flag; int HDF_Band8_flag; int HDF_Band9_flag; unsigned char *uchar_array; unsigned short int *ushort_array; unsigned int *ulong_array; short int *short_array; unsigned char *byte_array; /* these arrays will hold the data to transfer */ float32 *Latitude_array; float32 *Longitude_array; float32 *BAND1_array; float32 *BAND2_array; float32 *BAND3_array; float32 *BAND4_array; float32 *BAND5_array; float32 *BAND6_array; float32 *BAND7_array; float32 *BAND8_array; float32 *BAND9_array; float32 *float_array; McArgSyntax filesyntax = {".", "=", ";", "{\"", "}", "'", "'", NULL, "X", " "}; servacct requestBlock; /* request block */ unsigned int value; /* EOS data value */ /* 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 MOD3AGET V1.1 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); /* initialize the context file */ rc = M0SetDefaultFiles( (const char*)NULL, CONTEXT_FILES, NUM_CONTEXT_FILES ); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Failed to locate context file"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* get dataset info */ rc = M0sxdatasetinfo(request, &group, &dataset, &type, &format, &mask, &info, &comment, &loBound, &hiBound, &rt_flag); sprintf(trace_string, "%s Dataset Group = %s", server,group); M0sxtrce( trace_string ); sprintf(trace_string, "%s File Mask = %s", server,mask); M0sxtrce( trace_string ); /* 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); } sprintf(trace_string, "%s Number of Matching Files = %d", server,num_flist); M0sxtrce( trace_string ); /* POS sort condition */ rc = Mcargint(0, " ", 2, 0, -99999, num_flist, &iPos, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Beginning Position"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return (0); } bPos = iPos; if( bPos <= 0 ) { ePos = num_flist + bPos; if( ePos <= 0 ) ePos = 1; bPos = ePos; } else { ePos = bPos; } sprintf(trace_string, "%s bPos: %d, ePos: %d", server, bPos, ePos); M0sxtrce( trace_string ); /* Current Day and Time */ rc = Mcgetdaytime(&curDate, &curTime); /* DAY */ if( Mcargnum(0, "DAY") != 0 ) { rc = Mcargiyd(0, "DAY", 1, curDate, 1972001, curDate, &bdate, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid DAY format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( iPos <= 0 && rc != 300) { bPos = 1; ePos = num_flist; } rc = Mcargiyd(0, "DAY", 2, bdate, bdate, curDate, &edate, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid DAY format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } else { bdate = 1972001; edate = curDate; } (void *)sprintf(trace_string,"%s DAY: range= %d to %d",server,bdate,edate); M0sxtrce( trace_string ); /* TIME */ if( Mcargnum(0, "TIM.E" ) != 0 ) { rc = Mcargihr(0, "TIM.E", 1, 0, 0, 235959, &btime, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid TIME format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( iPos <= 0 && rc != 400) { bPos = 1; ePos = num_flist; } rc = Mcargihr(0, "TIM.E", 2, btime, 0, 235959, &etime, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid TIME format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( rc == 400 ) etime = 235959; } else { btime = 0; etime = 235959; } (void *)sprintf(trace_string,"%s TIME: range= %d to %d",server,btime,etime); M0sxtrce( trace_string ); /* Process the request: Dataset Position */ loBound = (num_flist * -1) +1; hiBound = num_flist; rc = Mcargint(0, "", 2, 0, loBound, hiBound, &image_dataset_position, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Dataset Position format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* PLACE */ rc = Mcargstr(0, "", 3, "AU", (const char **)&place); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Coordinate format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } request_lalo_flag = FALSE; request_image_flag = FALSE; request_area_flag = FALSE; if( strcmp(place,"EC") == 0 || strcmp(place,"EU") == 0 ) request_lalo_flag = TRUE; if( strcmp(place,"IC") == 0 || strcmp(place,"IU") == 0 ) request_image_flag = TRUE; if( strcmp(place,"AC") == 0 || strcmp(place,"AU") == 0 ) request_area_flag = TRUE; /* Process the request: Latitude/Longitude*/ if( request_lalo_flag == TRUE ) { rc = Mcargdll(0, " ", 4, (double)999.0, (double)-90.0, (double)90.0, &request_center_latitude, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid LATitude format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } rc = Mcargdll(0, " ", 5, (double)999.0, (double)-180.0, (double)180.0, &request_center_longitude, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid LONgitude format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } request_center_longitude = -request_center_longitude; (void *)sprintf(trace_string,"%s Center Earth COORD: Lat=%f Lon=%f" ,server,request_center_latitude,request_center_longitude); M0sxtrce( trace_string ); } /* Process the request: Satellite Line/Element */ else if( request_image_flag == TRUE ) { rc = Mcargint(0, "", 4, 1, 1, 0, &request_starting_line, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid LINe format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } rc = Mcargint(0, "", 5, 1, 1, 0, &request_starting_element, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid ELEment format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } (void *)sprintf(trace_string,"%s Starting Image COORD: Lin=%d Ele=%d" ,server,request_starting_line,request_starting_element); M0sxtrce( trace_string ); } /* Process the request: Image Line/Element */ else if( request_area_flag == TRUE ) { rc = Mcargint(0, "", 4, 0, 1, 0, &read_starting_line, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid LINe format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } rc = Mcargint(0, "", 5, 0, 1, 0, &read_starting_element, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid ELEment format"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } (void *)sprintf(trace_string,"%s Starting Area COORD: Lin=%d Ele=%d" ,server,read_starting_line,read_starting_element); M0sxtrce( trace_string ); } /* Process the request: Line Magnification */ rc = Mcargint(0, "LMA.G", 1, 1, -50, 1, &request_line_magnification, &dum); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Line MAG specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_line_magnification == 0 ) request_line_magnification = 1; if( request_line_magnification < 0 ) request_line_magnification = -(request_line_magnification);; /* Process the request: Element Magnification */ rc = Mcargint(0, "EMA.G", 1, 1, -50, 1, &request_element_magnification, &dum); (void *)sprintf(trace_string,"%s EMAG status = %d", server, rc); M0sxtrce( trace_string ); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Element MAG specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } if( request_element_magnification == 0 ) request_element_magnification = 1; if( request_element_magnification < 0 ) request_element_magnification = -(request_element_magnification); (void *)sprintf(trace_string,"%s MAG: Lin=%d Ele=%d" ,server,request_line_magnification,request_element_magnification); M0sxtrce( trace_string ); /* SIZE */ rc = Mcargint(0, "", 7, 480, 1, 99999, &request_line_size, &dum ); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Line SIZE specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } rc = Mcargint(0, "", 8, 640, 1, 99999, &request_element_size, &dum ); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Element SIZE specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } (void *)sprintf(trace_string,"%s SIZE: Lin=%d Ele=%d" ,server,request_line_size,request_element_size); M0sxtrce( trace_string ); /* BAND */ request_n_bands = Mcargnum(0, "BAN.D" ); if( request_n_bands == 0 ) { (void)strcpy(requestBlock.errormsg, "No BAND(s) specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } else { char *cALL; /* BAND=ALL*/ rc = Mcargstr(0, "BAN.D", 1, " ", (const char **)&cALL); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid BAND specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* Transfer ALL bands */ if( strncmp( cALL, "ALL",3 ) == 0 ) { for( i =0; iMODIS_GEO_MAX_BAND ) { (void)strcpy(requestBlock.errormsg, "Specified BAND not contained in image"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* set image constants */ 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.0; image_geo_longitude_resolution = 20.0; image_geo_nav_offset = 0; nav_offset = 0; } } else { sprintf(trace_string, "%s FILE RESOLUTION: FAILED for %s", server, file_name); M0sxtrce( trace_string ); break; } /* 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, "", 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 #DataSets=%d", server,n_datasets); M0sxtrce( trace_string ); /* loop through the individual SDS's */ for( index=0; indeximage_geo_maximum_latitude ) image_geo_maximum_latitude = BAND1_array[i]; } } /* adjust geo field for resolution reduction */ image_geo_line_size = sds_dim_sizes[0]/5; pad = sds_dim_sizes[1]; if( pad%4 != 0 ) { pad = pad/4; pad = (pad+1)*4; } image_geo_element_size = pad/5; image_geo_ending_line = image_geo_line_size + 1; image_geo_ending_element = image_geo_element_size + 1; /* reserve memory for the Latitude array */ Latitude_array = malloc( (image_geo_line_size * image_geo_element_size) * sizeof(float32) ); if( Latitude_array == NULL ) { (void *)sprintf(trace_string,"%s Failed to aquire memory for Latitude",server); M0sxtrce( trace_string ); } else { jj = 0; for( i=0; iimage_geo_maximum_longitude ) image_geo_maximum_longitude = BAND2_array[i]; } } /* adjust geo field for resolution reduction */ image_geo_line_size = sds_dim_sizes[0]/5; pad = sds_dim_sizes[1]; if( pad%4 != 0 ) { pad = pad/4; pad = (pad+1)*4; } image_geo_element_size = pad/5; image_geo_ending_line = image_geo_line_size + 1; image_geo_ending_element = image_geo_element_size + 1; /* reserve memory for the Longitude array */ Longitude_array = malloc( (image_geo_line_size * image_geo_element_size) * sizeof(float32) ); if( Longitude_array == NULL ) { (void *)sprintf(trace_string,"%s Failed to aquire memory for Longitude",server); M0sxtrce( trace_string ); } else { jj = 0; for( i=0; i image_geo_maximum_latitude || request_center_longitude < image_geo_minimum_longitude || request_center_longitude > image_geo_maximum_longitude ) { sprintf(trace_string, "%s segment fails lat/lon bounds", server); M0sxtrce( trace_string ); return (-1); } /* 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_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_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_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_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 ); /* *************************** Transfer starts here ***************************** */ (void *)sprintf(trace_string,"%s TRANSFER",server); M0sxtrce( trace_string ); /* size of a lat/lon transfer array */ lalo_array_line_size = (read_geo_line_size / image_geo_line_magnification); if ( lalo_array_line_size <= 1 ) lalo_array_line_size = 2; lalo_array_elem_size = (read_geo_element_size / image_geo_element_magnification); 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 ); (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 */ (void *)sprintf(trace_string,"%s DATA BLOCK CALC ",server); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ SIZE line=%d elem=%d",server, read_line_size, read_element_size); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ MAG line=%d elem=%d",server, request_line_magnification, request_element_magnification ); M0sxtrce( trace_string ); (void *)sprintf(trace_string,"%s READ SIZE bands=%d bpe=%d prefix=%d",server, request_n_bands, request_data_size, psize ); M0sxtrce( trace_string ); 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]; } } } } /* 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 */ M0swbyt4( &nav_block[2], NAV_BLOCK_SIZE-2 ); 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 ***************** */ /* initialize the calibration block */ for( i=0; i=0 && i=0 && j=0 && i=0 && j 1 ) { memcpy( (void *)&uchar_array[0], (void *)&level_map[0], psize ); } } if( space == 2 ) { ushort_array = malloc( (psize/2) + (request_n_bands*request_element_size*sizeof(unsigned short int)) ); if( ushort_array == NULL ) { (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 ); } } if( space == 4 ) { ulong_array = malloc( (psize/4) + (request_n_bands*request_element_size*sizeof(unsigned int)) ); if( ulong_array == NULL ) { (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 Output unit =%d", server,ounit_flag); M0sxtrce( trace_string ); for( i=0; i=0 && i=0 && j RAW */ if( ounit_flag == 0 ) { if( rvalue == band_fils[band-1] ) { value = 99990000; } else { if( band == 1 ) value = (rvalue + 90.0) * 10000.0; if( band == 2 ) value = (rvalue + 180.0) * 10000.0; if( band == 3 ) value = (rvalue + 400.0) * 10000.0; if( band == 4 ) value = (rvalue + 0.0) * 10000.0; if( band == 5 ) value = (rvalue + 180.0) * 10000.0; if( band == 6 ) value = (rvalue + 0.0) * 10000.0; if( band == 7 ) value = (rvalue + 180.0) * 10000.0; if( band == 8 ) value = (rvalue + 0.0) * 1.0; if( band == 9 ) value = (rvalue + 0.0) * 25.0; } } /* RAW --> BRIT */ if( ounit_flag == 2 ) { if( rvalue == band_fils[band-1]) { value = 3; } else if( rvalue < band_mins[band-1] ) { value = 5; } else if( rvalue > band_maxs[band-1] ) { value = 255; } else { value = ((rvalue-band_mins[band-1])/band_maxs[band-1]) * 250.0 + 0.5; } } } /* 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] = (unsigned long)value; } /* increment the element counter */ jj = jj+1; } /* End of the BAND loop */ } /* 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 ); } } /* FREE the HDF-EOS array */ free( BAND1_array ); free( BAND2_array ); for( i=0; i