/* * Copyright(c) 2015, Space Science and Engineering Center, UW-Madison * Refer to "McIDAS Software Acquisition and Distribution Policies" * in the file mcidas/data/license.txt */ /**** $Id: abinaget.c,v 1.66 2021/08/05 20:39:13 russd Tst $ ****/ /* ** Name: ** abinaget : ADDE data server for GOES-R NOAAPort image server uses SQL database ** ** 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 reads GOES-R series images from NetCDF data format ** ** Categories: ** ADDE server */ #include #include #include #if defined(__APPLE__) #include #endif #include #include /* <<<<< UPC add 20190425 - for 'basename' >>>>> */ #include /* <<<<< UPC add 20190507 - for regcomp, regexec >>>>> */ #include /* <<<<< UPC add 20190507 - for regcomp, regexec >>>>> */ #include "mcidas.h" #include "mcidasp.h" #include "mcncdf.h" #include "m0arg.h" #include "AreaDir.h" #include "SDIUtil.h" #include "m0glue.h" #include "math.h" /* SQLite database include */ #include "sqlite3.h" /* NetCDF include files */ #include "netcdf.h" /* ABIN include files */ #include "abinparm.h" /* Prototypes */ int **malloc2dint(int, int); char **GetRegexpMatchList( const char *, const char * ); Fint lit_( const char *, FsLen ); char trace_string[500]; /* trace text */ #define tprintf(str, ...) \ do { \ extern Fint trace_; \ if (trace_) { \ sprintf(str, __VA_ARGS__); \ M0sxtrce(str); \ } \ } while (0) int main ( int argc, char *argv[] ) /* ** AREA structure: ** directory - 64 4-byte words ** nav - 128 4-byte words ** cal - 18*64 4-byte words ABIN calibration type ** - 7*64 4-byte words SCMI calibration type ** aux - 0 4-byte words ** data */ /* CONSTANTS */ #define TRUE 1 /* TRUE flag */ #define FALSE 0 /* FALSE flag */ #define IMAGE_FILE_VERSION 4 /* AREA ID type element */ #define DIR_SIZE 64 /* size of the diectory block */ #define NAV_BLOCK_SIZE 128 /* NAV block size [words] */ #define AUX_BLOCK_SIZE 0 /* AUX block size [words] */ #define ABI_NAV_OFFSET 4*DIR_SIZE /* NAV block offset [bytes] */ #define DQF_SIZE 512 /* DQF block size */ #define MAX_STR_LEN 80 /* card length */ #define ABI_MAX_L1B 16 /* maximum number of bands supported */ #define ABI_MAX_BANDS 64 /* maximum number of Native */ #define ADB_MAX_BANDS 16 /* maximum number of SQLite bands */ #define ABI_RAW_SCALE 1.0 /* scaling for RAW data */ #define ABI_RAD_SCALE 1000.0 /* scaling for RAD data */ #define ABI_TEMP_SCALE 100.0 /* scaling for TEMP data */ #define ABI_ALB_SCALE 100.0 /* scaling for ALB data */ #define ABI_BRIT_SCALE 1.0 /* scaling for BRIT data */ #define SCMI 0 /* CAL type SCMI */ #define ABIN 1 /* CAL type ABIN */ #define ABI 0 /* image type ABIN aka L1b */ #define L2 1 /* image type L2 */ #define MATCH 11 #define QUERY_LEN 10240 /* size of the SQLite DB inquery */ #define NAME_LEN 50 /* size of database key name */ #define KEY_MAX 100 /* MAXIMUM number of key names */ #define FILE_MAX 24000 /* MAXIMUM number of file names */ #define SQLITE_OK 0 /* SQLite function result is OK */ { /* Internal Variables */ char llchar[4]={"LL "}; char level_map[ABI_MAX_BANDS]; /* prefix level map */ char *file_name; /* name of NetCDF file */ char *file_path; /* path of NetCDF file */ char *image_stype; /* image source type */ char *last_stype; /* previous source type */ char *dataset; /* dataset name */ char *def_unit; /* default UNIT */ char *dir_unit; /* directory UNIT */ char *var_name[ABI_MAX_BANDS]; /* variable name */ char *comment; /* ADDE comment field */ char *format; /* ADDE dataset format */ char *group; /* dataset group */ char *info; /* ADDE dataset info */ char *mask; /* dataset file mask */ char *place; /* coordinate system */ char *punit; /* parameter UNITS */ char *request; /* request string */ char *type; /* ADDE dataset type */ char *unit; /* UNITS keyword */ char *csstr; /* UNITS ORIG or EXP stretch */ char *prefix; /* line prefix */ char **flist = NULL; /* file list */ char **mlist = NULL; /* Array of matches for regexp */ char **fdatabase; /* Image tracking arrays */ int *seconds; int *sss; int *Nbands; int *cover; int *imode; int *ssp_lats; int *ssp_lons; int *pro_lons; int **lines; int **elems; int **bands; int **ivars; int **iress; int **gress; int **positions; int **DQF1s; int **DQF2s; int **DQF3s; int **DQF4s; int **DQF5s; int **DQF6s; int **DQF7s; int **DQF8s; int **YFacs; int **YOffs; int **XFacs; int **XOffs; const char *dum; /* dummy variable for arg routines */ const char server[] = {"ABINAGET"}; /* server name */ const char EREGEXP[] = ".._(ABI|GLM)-((L1b|L2)-(.{3,5})(F|C|M[12]|AK|HI|PR))-M([346])(_|C.._)G(1[6-9])_s(.{7})(.{6})"; double request_center_latitude; /* requested center latitude */ double request_center_longitude; /* requested center longitude */ int INVALID_VALUE = 0; /* Invalid data value */ float image_geo_latitude; /* CP latitude */ float image_geo_longitude; /* CP longitude */ float image_geo_line_resolution; /* image LALO line resolution */ float image_geo_element_resolution; /* image LALO element resolution */ float image_line_resolution; /* image line resolution */ float image_element_resolution; /* image element resolution */ float fResolution; /* file resolution */ float chunk_preempt; int DQF_iarray[DQF_SIZE]; unsigned short DQF_sarray[16]; float DQF_fvalue; Fint4 directory[DIR_SIZE]; /* image directory block */ Fint4 nav_block[NAV_BLOCK_SIZE]; /* NAV block */ Fint4 cal_block[18*ABI_MAX_BANDS]; /* CAL block */ int bdate, edate; /* beginning, ending date [CCYYDDD] */ int btime, etime; /* beginning, ending time [HHMMSS] */ int CalType; /* calibration type */ int curDate; /* current CCYYDDD */ int curTime; /* current HHMMSS */ int dat_block_size; /* data block size */ int def_space; /* default SPACE */ int loBound, hiBound; /* starting, ending dataset positions */ int PIXBYTE; int L2INDX; int i, j, k, N; /* loop indexes and array counters */ int NJ, NK; int iSSS; /* satellite number */ int indx; /* index pointer */ int num_flist; /* number of files */ int num_fdatabase; /* number of database files */ int num_columns; /* number of database colunms */ int ounit_flag=-999; /* output unit flag */ int pscale; /* parameter scale */ int psize; /* prefix size */ int rc; /* function return code */ int rt_flag; /* ADDE realtime flag */ int irem; /* modulus remainder */ int space; /* output spacing */ int totalSize; /* transfer byte count */ int trace = 0; /* trace flag */ int transaction = 0; /* transaction flag */ int user = 0; /* user id */ int band; /* band number */ int Pos; /* ADDE position number */ int bPos; /* Beginning ADDE position number */ int ePos; /* Ending ADDE position number */ int iPos; /* ADDE position increment */ int image_stype_flag; /* image source type flag */ int image_hms; /* image time */ int image_tmin; /* image delta min time */ int image_tmax; /* image delta max time */ int image_cyd; /* image date CCYYDDD format */ int image_iyd; /* image date AREA format */ int image_sec; /* image time in seconds */ int image_data_size; /* size of a data element in bytes */ int image_band; /* file image band */ int adde_pos; /* number of times */ int image_n_bands; /* number of image bands */ int ImageMode; /* ABI file name - Image Mode */ int ImagePlatform; /* ABI file name - Image Platform */ int ImageType; /* ABI file name - Image Type */ int NOBAND_SPECIFIED; /* FLAG: -> if user specified a BAND */ int ALLBANDS; /* FLAG: -> if user specified BAND=ALL */ int ALLSIZE; /* FLAG: -> if user specified SIZE=ALL */ int iBand; /* band from file name */ int pBands[ABI_MAX_BANDS]; /* band list for the current file */ int nmatch; /* number of matches expected */ int NpBands; /* # bands for the current file */ int iCoverage; /* coverage from file name */ int iResolution; /* SSEC resolution */ int gResolution; /* SSEC resolution */ int gotTime; int n_times; int var_ids[ABI_MAX_BANDS]; /* NetCDF variable id array */ int image_starting_line; /* image starting line */ int image_starting_element; /* image starting element */ int image_dataset_position; /* image position */ int ADDE_dataset_position; /* ADDE position */ int image_line_size; /* image line size */ int image_element_size; /* image element size */ int image_line_base_resolution; /* image base line resolution */ int image_element_base_resolution; /* image base element resolution */ int image_lines[ABI_MAX_BANDS]; /* image lines/rows */ int image_elems[ABI_MAX_BANDS]; /* image elements/cells */ int CAL_BLOCK_SIZE = 18*ABI_MAX_BANDS; /* CAL block size [words] */ int ABI_CAL_OFFSET = ABI_NAV_OFFSET+4*NAV_BLOCK_SIZE; /* CAL block offset [bytes] */ int ABI_AUX_OFFSET = 0; /* AUX block offset [bytes] */ int request_data_size; /* request element byte size */ int request_n_bands; /* request number of bands */ int request_bands[ABI_MAX_BANDS]; /* request band array */ int request_lalo_flag; /* request LALO flag */ int request_image_flag; /* request image flag */ int request_area_flag; /* request area flag */ int request_line_size; /* request line size */ int request_element_size; /* request element size */ int request_element_size_orig; /* request element size orig */ int request_line_resolution; /* request line resoluton */ int request_element_resolution; /* request element resolution */ int request_line_magnification; /* request line magnification */ int request_element_magnification; /* request element magnification */ int request_starting_line; /* request starting line */ int request_starting_element; /* request starting element */ int found_n_bands; /* image number of bands */ int found_bands[ABI_MAX_BANDS]; /* array of image bands */ int read_line_size; /* image read line size */ int read_element_size; /* image read element size */ int read_starting_line; /* image read startng line */ int read_starting_element; /* image read starting eleemnt */ int read_ending_line; /* image read ending line */ int read_ending_element; /* image read ending element */ int read_geo_line_size; /* image LALO line size */ int read_geo_element_size; /* image LALO element size */ int read_geo_starting_line; /* image LALO starting line */ int read_geo_starting_element; /* image LALO starting element */ int read_geo_ending_line; /* image LALO ending line */ int read_geo_ending_element; /* image LALO ending element */ int size; /* size test variable */ int OUTSIZE; /* output line size */ int SAMPLE_size; /* input data sample size */ int TimeBaseSearch; int TimeBasePos; int init_line; int init_elem; int currentOpn; int options[5]; int options_out[5]; int len_unit; int var_iname; int iscale; /* ADDE client request block */ servacct requestBlock; /* request block text */ unsigned char *uchar_array; /* 1 byte output array */ unsigned int *ulong_array; /* 4 byte output array */ unsigned int value; /* 4 byte output variable */ unsigned short int *ushort_array; /* 2 byte output array */ /* MultiBand variables */ int this_resolution; int lowest_resolution; int highest_resolution; int Nfound; int iband; int linc; int einc; int lsize; int esize; int iline; int jelem; int band_sample[ABI_MAX_BANDS]; int band_nav; int band_alloc; int MultiBand_flag; int MultiBandL2_flag; int MultiBand_res; int MultiBand_resBand; int MultiBand_Nmap; int MultiBand_map[ABI_MAX_BANDS]; /* NetCDF related declaration */ int ncdf_ids[ABI_MAX_BANDS]; int dim_id; int var_id; int WaveLength_id; int kappa_id; int planckFK1_id; int planckFK2_id; int planckBC1_id; int planckBC2_id; int image_ul_line; int image_ul_element; int ONE = 1; int TWO = 2; int LL; int VAR_ndims[ABI_MAX_BANDS]; float lfac[ABI_MAX_BANDS]; /* line scale factor */ float cfac[ABI_MAX_BANDS]; /* element scale factor */ float loff[ABI_MAX_BANDS]; /* line add offset */ float coff[ABI_MAX_BANDS]; /* element add offset */ float ssp_lat; /* subpoint latitude */ float ssp_lon; /* subpoint longitude */ float pro_lon; /* projection lon - WCS3 */ float VAR_vmin[ABI_MAX_BANDS]; float VAR_vmax[ABI_MAX_BANDS]; float VAR_scale[ABI_MAX_BANDS]; float VAR_offset[ABI_MAX_BANDS]; float WaveLength[ABI_MAX_BANDS]; float kappa[ABI_MAX_BANDS]; float planckFK1[ABI_MAX_BANDS]; float planckFK2[ABI_MAX_BANDS]; float planckBC1[ABI_MAX_BANDS]; float planckBC2[ABI_MAX_BANDS]; Freal Fline; Freal Felem; Freal Flat; Freal Flon; Freal Fdummy; short *Xarray; /* element coordinate array */ short *Yarray; /* line coordinate array */ unsigned short *Cnt_array; /* unsigned short array */ unsigned int *Wrd_array; /* unsigned int array */ short VAR_FillValue[ABI_MAX_BANDS]; size_t rows; size_t cells; size_t start[] = {0,0}; size_t stride[] = {0,0}; size_t chunk_size; size_t chunk_nelems; size_t *chunkp; /* SQLite Database mods */ char * query1; char * query2; char * params_query; char * database_query; char * table_query; char * key_name; char * fname; char * fpath; char * char_value; char * key_names[KEY_MAX][50]; char * *file_names; char * *file_paths; char * *file_open; char *database; /* path to the SQLITE database */ char *tables; /* tables within the SQLITE database */ char *sqlite_errormsg = 0; float DQF_float; int Nkey; int Nrec; int Nfile; int Nfile_open; int DBstep; int int_value1; int int_value2; int key_len; int file_len; int path_len; int database_present; /* does the DB exist */ int database_use; /* if DB exists do we want to use it */ int database_switch; int status; int handle; int length; int Ntables; int sqlite_status=0; int NULLSelect=0; /* Is select string NULL?*/ int key_locs[KEY_MAX]; int THIS_SEC; int channel; int DQF1; int DQF2; int DQF3; int DQF4; int DQF5; int DQF6; int DQF7; int DQF8; int MAX_BANDS; int jPos; int image_cp_line; int image_cp_element; int image_sqlines; int image_sqelems; float sqlfac; float sqloff; float sqcfac; float sqcoff; typedef struct sqlite sqlite; McArgSyntax filesyntax = {" ", "=", ";", "{\"", "}", "'", "'", NULL, "X", " "}; McArgSyntax datasyntax = {" ", "=", ";", "'", "'", NULL, "X", " "}; sqlite3 *sqlite_conn; sqlite3_stmt *selectStatement; /* SQLite Database mods */ /* To use two words for band mask */ union abibnd { unsigned int lBand[2]; unsigned long bandmap; } abiband; /* ************************************************************************* ** Step 1: process the transaction request ** Use standard function calls to retrieve the parameters in the ** comm block. ** ************************************************************************* */ /* Initialize the MAX_BANDS to ABI_MAX_BANDS */ MAX_BANDS = ABI_MAX_BANDS; /* Initialize local server */ rc = M0InitLocalServer(server, argc, argv, &requestBlock, &request); /* See if logging should be done, determined by hidden TRACE= flag */ trace = M0IsTraceSet(request); tprintf(trace_string,"%s ABI SQLite DB DATA SERVER V1.65 DB",server); /* 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); tprintf(trace_string, "%s group = %s", server,group); tprintf(trace_string, "%s dataset = %s", server,dataset); tprintf(trace_string, "%s type = %s", server,type); tprintf(trace_string, "%s format = %s", server,format); tprintf(trace_string, "%s mask = %s", server,mask); tprintf(trace_string, "%s comment = %s", server,comment); tprintf(trace_string, "%s Request = %s", server,request); tprintf(trace_string, "%s Dataset = %s", server,group); tprintf(trace_string, "%s L1b SS = %d", server,ABISSS); tprintf(trace_string, "%s L2 SS = %d", server,L2SSS); tprintf(trace_string, "%s L2 Nprods = %d", server,L2NPRODS); tprintf(trace_string, "%s File Mask = %s", server,mask); tprintf(trace_string, "%s Info Mask = %s", server,info); tprintf(trace_string, "%s rt_flag = %d", server,rt_flag); #if 0 for( i=0; i<=L2NPRODS-1; i++ ) { tprintf(trace_string,"%s L2 Names[%d]=%s Bands[%d]=%d Coverage[%d]=%d", server,i+1,L2NAMES[i], i+1,L2BANDS[i], i+1,L2COVERS[i] ); } #endif /* ************************************************************************* ** Step 1.2: Inquire if the DB is present ** ** Some Rules ** - set DB switch to ON by default ** - set DB switch to OFF if NOT archive dataset ** - set DB switch to OFF if transaction variable is OFF ** - set DB switch to OFF if DB is NOT present ** variable database_switch = 0 means NOT a sqlit3 dataset * ************************************************************************** */ /* check for DB switch */ database_switch = 0; if( rt_flag == 2 ) database_switch = 1; /* CHECK IF DATABASE SWITCH IS NOT SET */ if( database_switch == 0 ) goto GREP_FOR_FILES; /* Set the MAX_BANDS to ADB_MAX_BANDS */ MAX_BANDS = ADB_MAX_BANDS; /* Allocate arrays for SQLite Query */ params_query = calloc((size_t)QUERY_LEN, sizeof(char)); database_query = calloc((size_t)QUERY_LEN, sizeof(char)); table_query = calloc((size_t)QUERY_LEN, sizeof(char)); query1 = calloc((size_t)QUERY_LEN, sizeof(char)); query2 = calloc((size_t)QUERY_LEN, sizeof(char)); fpath = calloc((size_t)QUERY_LEN, sizeof(char)); key_name = calloc((size_t)NAME_LEN, sizeof(char)); if( params_query == NULL || database_query == NULL || table_query == NULL || query1 == NULL || query2 == NULL || key_name == NULL ) { /* tprintf(trace_string,"%s Can't allocate SQLite database Query strings", server); */ strcpy(requestBlock.errormsg, "Can't allocate SQLite Query strings"); sqlite3_close(sqlite_conn); requestBlock.returncode = -10; M0sxdone(&requestBlock); return(0); } if( database_switch == 1 ) { tprintf(trace_string, "%s DataBase Switch is ON", server); /* Parse the INFO string into its components */ handle = Mcargparse( info, &datasyntax, &length); status = Mcargstr(handle, "DATABASE", 1, (char *)NULL, &database ); /* Produce a list of files matching the pattern info */ fdatabase = M0GetMaskFileList(database); if( fdatabase == (char **)NULL ) { strcpy(requestBlock.errormsg, "No images satisfy database selection criteria"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } else { num_fdatabase = VecLen(fdatabase); if( num_fdatabase <= 0 ) { (void)strcpy(requestBlock.errormsg, "No files found matching file info"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } } /* test for SQLite3 database */ status = M0ImgSQLiteDB_tables( fdatabase[0], Ntables, tables ); /* open the SQLite database */ /* tprintf(trace_string, "%s Opening SQLite database"); */ rc= sqlite3_open_v2(fdatabase[0],&sqlite_conn,SQLITE_OPEN_READONLY,NULL); if( rc != 0 ){ tprintf(trace_string,"%s Can't open SQLite database: %s", server,sqlite3_errmsg(sqlite_conn)); strcpy(requestBlock.errormsg, "Can't Open SQLite database"); sqlite3_close(sqlite_conn); requestBlock.returncode = -10; M0sxdone(&requestBlock); return(0); } /* tprintf(trace_string,"%s SQLite database is OPEN\n", server); */ /* Add SQLite Query directives */ rc=sqlite3_exec(sqlite_conn,"PRAGMA synchronous = OFF", NULL, NULL, &sqlite_errormsg); /* tprintf(trace_string,"%s PAST PRAGMA synchronous rc=%d %s\n", server, rc, sqlite_errormsg); */ /* *************************************************************************************** */ /* Step 1 - Get a list of the keys Save a list of the key names construct the SELECT clause for the Entries Table */ /* Append to Select clause GET EVERYTHING from the keys table` */ sprintf(table_query,"SELECT * FROM Keys"); /* tprintf(trace_string,"%s table_query string >%s<\n", server,table_query); */ /* PREPARE the tranaction */ rc=sqlite3_prepare_v2(sqlite_conn,table_query,QUERY_LEN,&selectStatement,0); /* tprintf(trace_string,"%s PAST PREPARE rc=%d\n", server,rc); */ /* Begin the transaction */ rc=sqlite3_exec(sqlite_conn,"BEGIN TRANSACTION", NULL, NULL, &sqlite_errormsg); /* tprintf(trace_string,"%s PAST EXECUTE rc=%d %s\n", server,rc, sqlite_errormsg); */ if( rc != SQLITE_OK ) { /* tprintf(trace_string,"%s FAILED to fetch Keys table", server); */ strcpy(requestBlock.errormsg, "Can't Query Keys Table"); sqlite3_close(sqlite_conn); requestBlock.returncode = -10; M0sxdone(&requestBlock); return(0); } /* Initialize the param_query string */ sprintf(query1, "SELECT "); strcat(params_query,query1); /* Initialize the database_query string */ sprintf(query2, "FROM Entries "); strcat(database_query,query2); /* step through the transaction */ Nkey = 0; rc = sqlite3_step(selectStatement); while ( rc == SQLITE_ROW ) { /* Save the key names */ /* tprintf(trace_string,"%s THIS KEY = %s", server,sqlite3_column_text(selectStatement,0)); */ key_name = (char*) (sqlite3_column_text(selectStatement, 0)); key_len = strlen( key_name ); strncpy(key_names[Nkey], key_name, key_len+1); /* tprintf(trace_string,"%s KEY = %s LEN=%d", server,key_names[Nkey],key_len); */ /* construct the params_query clause */ sprintf(query1, "%s_Keys.value,", sqlite3_column_text(selectStatement,0) ); strcat(params_query,query1); /* construct the database_query clause */ sprintf(query2, "LEFT JOIN %s_Keys ON Entries.%s = %s_Keys.key ", sqlite3_column_text(selectStatement,0), sqlite3_column_text(selectStatement,0), sqlite3_column_text(selectStatement,0) ); strcat(database_query,query2); Nkey++; rc = sqlite3_step(selectStatement); } /* Append non-keyed values to the Keys list */ strcpy(key_names[Nkey], "Channel"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "NominalSubpointLatitude"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "NominalSubpointLongitude"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "ProjectionLongitude"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "YScaleFactor"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "YAddOffset"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "XScaleFactor"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "XAddOffset"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQGoodPct"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQCondUnusablePct"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQOutOfRangePct"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQNoValuePct"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQFPTExceedPct"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQFPTMaximumTemp"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQFPTThreshIncreaseTemp"); key_len = strlen( key_names[Nkey] ); Nkey++; strcpy(key_names[Nkey], "DQFPTThreshDecreaseTemp"); key_len = strlen( key_names[Nkey] ); Nkey++; /* Append the Filenames key */ strcpy(key_names[Nkey], "filename"); key_len = strlen( key_names[Nkey] ); Nkey++; /* Append non-keyed values to the query1 string */ sprintf(query1, "Entries.Channel,"); strcat(params_query,query1); sprintf(query1, "Entries.NominalSubpointLatitude,"); strcat(params_query,query1); sprintf(query1, "Entries.NominalSubpointLongitude,"); strcat(params_query,query1); sprintf(query1, "Entries.ProjectionLongitude,"); strcat(params_query,query1); sprintf(query1, "Entries.YScaleFactor,"); strcat(params_query,query1); sprintf(query1, "Entries.YAddOffset,"); strcat(params_query,query1); sprintf(query1, "Entries.XScaleFactor,"); strcat(params_query,query1); sprintf(query1, "Entries.XAddOffset,"); strcat(params_query,query1); sprintf(query1, "Entries.DQGoodPct,"); strcat(params_query,query1); sprintf(query1, "Entries.DQCondUnusablePct,"); strcat(params_query,query1); sprintf(query1, "Entries.DQOutOfRangePct,"); strcat(params_query,query1); sprintf(query1, "Entries.DQNoValuePct,"); strcat(params_query,query1); sprintf(query1, "Entries.DQFPTExceedPct,"); strcat(params_query,query1); sprintf(query1, "Entries.DQFPTMaximumTemp,"); strcat(params_query,query1); sprintf(query1, "Entries.DQFPTThreshIncreaseTemp,"); strcat(params_query,query1); sprintf(query1, "Entries.DQFPTThreshDecreaseTemp,"); strcat(params_query,query1); /* Terminate the param_query string */ sprintf(query1, "Filenames.filename "); strcat(params_query,query1); /* combine the two query strings */ strcat(params_query,database_query); /* NEW 03/31/21 - append Filenames Table */ sprintf(query1, "LEFT JOIN Filenames ON Entries.entry_index = Filenames.entry_index "); strcat(params_query,query1); /* NEW 03/11/21 - append ORDER BY to time sort the query results */ sprintf(query1, "ORDER BY Time_Keys.value "); strcat(params_query,query1); /* End the transaction */ rc=sqlite3_exec(sqlite_conn,"END TRANSACTION", NULL, NULL, &sqlite_errormsg); /* tprintf(trace_string,"%s PAST EXECUTE rc=%d %s\n", server,rc, sqlite_errormsg); */ /* initialize pointers to key names */ for( i=0; i 1 ) { /* Close database[0] */ sqlite3_close(sqlite_conn); /* loop through additional DBs */ for( N=1; N%s<\n", server,table_query); */ /* PREPARE the tranaction rc=sqlite3_prepare_v2(sqlite_conn,table_query,QUERY_LEN,&selectStatement,0); tprintf(trace_string,"%s PAST PREPARE rc=%d\n", server,rc); */ /* Begin the transaction rc=sqlite3_exec(sqlite_conn,"BEGIN TRANSACTION", NULL, NULL, &sqlite_errormsg); if( rc != SQLITE_OK ) { tprintf(trace_string,"%s FAILED to fetch Filenames table", server); strcpy(requestBlock.errormsg, "Can't Query Filenames Table"); sqlite3_close(sqlite_conn); requestBlock.returncode = -10; M0sxdone(&requestBlock); return(0); } tprintf(trace_string,"%s PAST EXECUTE rc=%d %s\n", server,rc, sqlite_errormsg); */ /* step through the transaction Nfile = 0; rc = sqlite3_step(selectStatement); while ( rc == SQLITE_ROW ) { fname = (char*) (sqlite3_column_text(selectStatement, 1)); file_len = strlen( fname ); strncpy(file_names[Nfile], fname, file_len+1); tprintf(trace_string,"%s FILENAME = %s LEN=%d", server,file_names[Nfile],file_len); Nfile++; rc = sqlite3_step(selectStatement); } */ /* End the transaction rc=sqlite3_exec(sqlite_conn,"END TRANSACTION", NULL, NULL, &sqlite_errormsg); tprintf(trace_string,"%s PAST EXECUTE rc=%d %s\n", server,rc, sqlite_errormsg); */ /* *************************************************************************************** */ /* Step 4 - Read the Entries table */ /* Initalization */ DBstep = 0; THIS_SEC = -1; n_times = 0; Nrec = 0; /* ********* loop through the DBs ******** */ for( N=0; N 0 ) { tprintf(trace_string, "%s Opening SQLite database",server); rc= sqlite3_open_v2(fdatabase[N],&sqlite_conn,SQLITE_OPEN_READONLY,NULL); if( rc != 0 ){ tprintf(trace_string,"%s Can't open SQLite database: %s", server,sqlite3_errmsg(sqlite_conn)); strcpy(requestBlock.errormsg, "Can't Open SQLite database"); sqlite3_close(sqlite_conn); requestBlock.returncode = -10; M0sxdone(&requestBlock); return(0); } } /* PREPARE the tranaction */ rc=sqlite3_prepare_v2(sqlite_conn,params_query,QUERY_LEN,&selectStatement,0); /* tprintf(trace_string,"%s PAST PREPARE rc=%d\n", server,rc); */ /* Begin the transaction */ rc=sqlite3_exec(sqlite_conn,"BEGIN TRANSACTION", NULL, NULL, &sqlite_errormsg); /* tprintf(trace_string,"%s PAST EXECUTE rc=%d %s\n", server,rc, sqlite_errormsg); */ if( rc != SQLITE_OK ) { /* tprintf(trace_string,"%s FAILED to fetch DataBase Entries", server); */ strcpy(requestBlock.errormsg, "Can't Query Keys Table"); sqlite3_close(sqlite_conn); requestBlock.returncode = -10; M0sxdone(&requestBlock); return(0); } /* step through the transaction */ rc = sqlite3_step(selectStatement); if( rc != SQLITE_ROW ) tprintf(trace_string,"%s SQLITE3_STEP Entries Failed with rc=%di Nrec=%d ", server,rc,Nrec); while ( rc == SQLITE_ROW ) { Nrec++; /* tprintf(trace_string,"%s GOT A RECORD: Nrec=%d", server,Nrec); */ /* Initialize variables */ image_cyd = -1; image_iyd = -1; image_hms = -1; image_sec = -1; image_sqlines = -1; image_sqelems = -1; iCoverage = -1; ImageMode = -1; ImagePlatform = -1; NpBands = 0; iSSS = -1; ImageType = -1; iBand = -1; DQF1 = 65530; DQF2 = 65530; DQF3 = 65530; DQF4 = 65530; DQF5 = 65530; DQF6 = 65530; DQF7 = 65530; DQF8 = 65530; /* ImageType */ ImageType = ABI; CalType = 1; /* YEAR */ for( i=0; i lines */ for( i=0; i elems */ for( i=0; i BAND */ for( i=0; i 0 ) { for( i=0; i= 0 ) { Nbands[j]++; bands[j][iBand-1] = iBand; positions[j][iBand-1] = DBstep-1; lines[j][iBand-1] = image_sqlines; elems[j][iBand-1] = image_sqelems; iress[j][iBand-1] = iResolution; gress[j][iBand-1] = gResolution; DQF1s[j][iBand-1] = DQF1; DQF2s[j][iBand-1] = DQF2; DQF3s[j][iBand-1] = DQF3; DQF4s[j][iBand-1] = DQF4; DQF5s[j][iBand-1] = DQF5; DQF6s[j][iBand-1] = DQF6; DQF7s[j][iBand-1] = DQF7; DQF8s[j][iBand-1] = DQF8; YFacs[j][iBand-1] = (int)(sqlfac*iscale); YOffs[j][iBand-1] = (int)(sqloff*iscale); XFacs[j][iBand-1] = (int)(sqcfac*iscale); XOffs[j][iBand-1] = (int)(sqcoff*iscale); } /* go get another record */ rc = sqlite3_step(selectStatement); /* if( rc != SQLITE_ROW ) tprintf(trace_string,"%s NO MORE ROWS: rc=%d", server,rc); */ } /* End the transaction */ rc=sqlite3_exec(sqlite_conn,"END TRANSACTION", NULL, NULL, &sqlite_errormsg); /* tprintf(trace_string,"%s END TRANSACTION rc=%d %s\n", server,rc, sqlite_errormsg); */ /* deallocate memory used by the sqlite_exec */ sqlite3_finalize(selectStatement); /* CLOSE the SQLite database */ sqlite3_close(sqlite_conn); /* ******** end of DB loop ********** */ } tprintf(trace_string,"%s Number of Data Entries = %d", server,num_flist); tprintf(trace_string,"%s Number of Unique Times = %d\n", server,n_times); /* using the SQLITE database */ database_switch = 1; /* ************************************************************************************ */ /* tprintf(trace_string, "%s MySQL Database TERMINATION ", server); */ goto REQUEST_CHECK; /* JUMP HERE IF WE ARE NOT USING A SQLITE DATABASE */ GREP_FOR_FILES: /* ************************************************************************* ** Step 2: Get a list of file names matching the ADDE file mask ** ** ************************************************************************* */ /* 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); } else { num_flist = VecLen(flist); if( num_flist <= 0 ) { (void)strcpy(requestBlock.errormsg, "No files found matching file mask"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } tprintf(trace_string, "%s Number of files found = %d", server,num_flist); } /* jump here if SQLite */ REQUEST_CHECK: /* ************************************************************************* ** Step 3: Analyze the request parameters ** ** POS - ADDE position number ** DAY - image Bday<->Eday ** TIME - image Btime<->Etime ** PLACE - request sector reference positioning ** A=AREA, I-IMAGE, E=EARTH ** U=UPPER, C= CENTER ** example: EC = EARTH CENTER ** LMAG - line magnification ** EMAG - element magnification ** SIZE - line and element request size ** BAND - image band ** STYPE - Source type (RAW, BRIT) ** SPACE - bytes per element (1,2 or 4) ** UNIT - output units (RAW, BRIT) ** ** ************************************************************************* */ /* 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( strncmp(place,"EC",2) == 0 || strncmp(place,"EU",2) == 0 ) request_lalo_flag = TRUE; if( strncmp(place,"IC",2) == 0 || strncmp(place,"IU",2) == 0 ) request_image_flag = TRUE; if( strncmp(place,"AC",2) == 0 || strncmp(place,"AU",2) == 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; tprintf(trace_string,"%s Center Earth COORD: Lat=%f Lon=%f" ,server,request_center_latitude,request_center_longitude); } else if( request_image_flag == TRUE ) { /* Image LINELE */ 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); } tprintf(trace_string,"%s Starting Image COORD: Lin=%d Ele=%d" ,server,request_starting_line,request_starting_element); } else if( request_area_flag == TRUE ) { /* Area LINELE */ 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); } tprintf(trace_string,"%s Starting Area COORD: Lin=%d Ele=%d" ,server,read_starting_line,read_starting_element); } /* Process the request: Line Magnification */ rc = Mcargint(0, "LMA.G", 1, 1, 0, -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, 0, -1, &request_element_magnification, &dum); 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);; tprintf(trace_string,"%s MAG: Lin=%d Ele=%d" ,server,request_line_magnification,request_element_magnification); /* 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_orig, &dum ); if( rc < 0 ) { (void)strcpy(requestBlock.errormsg, "Invalid Element SIZE specified"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* check for SIZE=ALL */ ALLSIZE=0; if( request_line_size==99999 && request_element_size_orig==99999 ) { ALLSIZE=1; } tprintf(trace_string,"%s ALLSIZE= %d" , server, ALLSIZE); /* Alter request elements to 4 byte boundry */ request_element_size = request_element_size_orig; if( request_element_size != 99999 ) { irem = request_element_size % 4; if( irem != 0 ) request_element_size = request_element_size + (4-irem); } tprintf(trace_string,"%s SIZE: Lin=%d Ele=%d" ,server,request_line_size,request_element_size); /* BAND */ NOBAND_SPECIFIED = 0; ALLBANDS = 0; request_n_bands = Mcargnum(0, "BAN.D" ); /* was the BAND= keyword entered */ if( request_n_bands == 0 ) { NOBAND_SPECIFIED = 1; if( ALLSIZE==1 ) ALLBANDS=1; } else { /* Transfer ALL bands */ char *cALL; /* BAND=ALL*/ rc = Mcargstr(0, "BAN.D", 1, " ", (const char **)&cALL); if( strncmp( cALL, "ALL",3 ) == 0 ) { request_n_bands = ABI_MAX_L1B; for( i=0; i 1 ) { /* Multi-band transfer list */ for( i=0; i 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer is not permitted for this data type"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } */ /* Now we are sure that the list is greater than 1 */ if( MultiBand_Nmap == 1 ) { request_n_bands = 1; } else { /* Re-construct the request list into ascending band order */ request_n_bands = 0; for( i=0; i= 6) { if( MultiBand_res < 4 ) { MultiBand_res = 4; MultiBand_resBand = request_bands[i]; } } } /* Multi-band transfer requires that the calibration is UNITS=RAW */ rc = Mcargstr(0, "UNI.T", 1, "RAW", (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 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer only permits RAW units"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* tprintf(trace_string,"%s MultiBand: Flag=%d Res=%d Band=%d Unit=%s", server,MultiBand_flag,MultiBand_res,MultiBand_resBand,unit); */ } } /* STYPE */ image_stype_flag = Mcargnum(0, "STY.PE" ); tprintf(trace_string,"%s image_stype_flag = %d",server,image_stype_flag); 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); } def_unit = stralloc("BRIT",NULL); def_space = 1; ABI_CAL_OFFSET = 0; CAL_BLOCK_SIZE = 0; ABI_AUX_OFFSET = 0; } else { def_unit = stralloc("RAW",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 = ABI_RAW_SCALE; punit = stralloc(" ",NULL); ounit_flag = 0; } else if( strncmp( unit, "RAD" ,3) == 0 ) { if( space == 0 ) space = 4; 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("RAD ",NULL); request_data_size = space; pscale = ABI_RAD_SCALE; punit = stralloc("MW**",NULL); /* Different radiance units for visible bands */ if( request_bands[0] < 7 ) punit = stralloc("WM**",NULL); ounit_flag = 1; } else if( strncmp( unit, "TEMP" ,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("TEMP",NULL); request_data_size = space; pscale = ABI_TEMP_SCALE; punit = stralloc("K ",NULL); ounit_flag = 2; } else if( strncmp( unit, "ALB" ,3) == 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("ALB ",NULL); request_data_size = space; pscale = ABI_ALB_SCALE; punit = stralloc("% ",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 = ABI_BRIT_SCALE; punit = stralloc(" ",NULL); ounit_flag = 4; /* Did not find a L1b base unit but it could be a product */ } else { /* Enforce RAW unit for multi-band transfer */ if( request_n_bands > 1 ) { (void)strcpy(requestBlock.errormsg, "Multi-band transfer UNITS must be RAW"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* Check to see if the unit is valid for an L2 product */ for( i=0; i>>>> */ tprintf(trace_string, "%s SECOND PASS file_name = %s", server, file_name); /* Does the file name match the filemask regular expression? */ mlist = GetRegexpMatchList( EREGEXP, file_name ); nmatch = VecLen( mlist ); if ( nmatch != MATCH ) { tprintf(trace_string, "%s SECOND PASS #match from GetRegexpMatchList = %d expected %d", server, nmatch, MATCH); continue; } /* ** mlist meanings: ** ** mlist[ 0] - name: OR_... ** mlist[ 1] - inst: ABI, GLM ** mlist[ 2] - pnam: L1b-Rad(C|F|...), L2-CMIP(C|F|...), L2-ADP(C|F|...), etc. ** mlist[ 3] - levl: L2, L1b ** mlist[ 4] - type: Rad, CMIP, ADP, ADC, ACM, etc. ** mlist[ 5] - covr: F, C, M1, M2, AK, HI, PR ** mlist[ 6] - mode: 3, 4, 6 ** mlist[ 7] - band: _, C01_, ..., C16_ ** mlist[ 8] - sat: 16, 17, 18, 19 ** mlist[ 9] - image_cyd: 2019127 (7 characters long) ** mlist[10] - image_hms: 042029 (6 characters long) */ /* ** CalType meanings: ** ** CalType - 0: SCMI ** CalType - 1: ABIN */ for( i=0; i 0 || image_lines[0] > 0 || image_elems[0] > 0 ) { if( n_times == 0 ) { /* Zero the file position array */ for( i=0; i= image_tmin && seconds[i] <= image_tmax ) && ( iCoverage == cover[i] ) && ( ImageMode == imode[i] ) && ( iSSS == sss[i] ) ) { if( image_sec != seconds[i] ) { image_sec = seconds[i]; rc = Mcsectodaytime( image_sec, &image_cyd, &image_hms ); } /* Record the band */ for( j=0; ji; j-- ) { seconds[j] = seconds[j-1]; cover[j] = cover[j-1]; imode[j] = imode[j-1]; sss[j] = sss[j-1]; for( k=0; k we exit the server */ if( n_times < 0 ) { (void)strcpy(requestBlock.errormsg, "No data files found"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return (0); } tprintf(trace_string, "%s SECOND PASS: Number of Unique times = %d", server, n_times); /* jump here if SQLite */ BYPASS_FILENAME: /* New location of POS, DATE and TIME argument handlers. Moved because we need to organize the file list based on image DATE and TIME instead of number of files returned from the glob function */ /* Position number specified */ adde_pos = n_times; rc = Mcargint(0, " ", 2, 0, -99999, adde_pos, &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 = adde_pos+bPos; if( ePos < 1 ) ePos = 1; bPos = ePos; } else { ePos = bPos; } tprintf(trace_string, "%s iPos=%d adde_pos=%d rc=%d", server,iPos,adde_pos,rc); tprintf(trace_string, "%s bPos=%d NPos=%d", server, iPos,adde_pos); tprintf(trace_string, "%s bPos: %d, ePos: %d", server, bPos, ePos); /* Current Day and Time */ rc = Mcgetdaytime(&curDate, &curTime); /* Switch for time based search =0 --> FALSE */ TimeBaseSearch = 0; /* DAY */ if( Mcargnum(0, "DAY") != 0 ) { /* Set TIME Base switch to TRUE */ /* Get the specified DATE */ 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 = adde_pos; TimeBaseSearch = 1; TimeBasePos = iPos; } 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; } /* 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 = adde_pos; TimeBaseSearch = 1; TimeBasePos = iPos; } 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; } /* Process the request: Dataset Position */ loBound = (adde_pos * -1) +1; hiBound = adde_pos; 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); } /* ************************************************************************* ** Step 7: MAIN LOOP ** ** At this point we have a list of files that have passed the ** date, time and dimension tests. The next step is to scan this ** list to verify that the dates and times meet any transaction conditions. ** ** If an image file passes the condition tests we read the file ** datasets to locate all of the "parts" we need to satisfy a data ** transfer. The necessary parts are: ** - navigation info ** - calibration info ** - Data array ** ** ************************************************************************* */ tprintf(trace_string, "%s BEFORE MAIN LOOP --- bPos=%d, ePos=%d", server, bPos, ePos); /* Initailize the band DQF array for this image (16values for 32bands = 512) */ for( i=0; i<512; i++ ) DQF_iarray[i] = 65530; found_n_bands = 0; for( ADDE_dataset_position=bPos; ADDE_dataset_position<=ePos; ADDE_dataset_position++) { /* For Time Based Search invert the position */ if( TimeBaseSearch == 0 ) { image_dataset_position = ADDE_dataset_position; } else { image_dataset_position = adde_pos - (ADDE_dataset_position-1); } /* Convert seconds to date and time */ rc = Mcsectodaytime( seconds[image_dataset_position-1], &image_cyd, &image_hms ); /* Convert julian date to image date */ rc = Mccydtoiyd( image_cyd, &image_iyd ); /* Check client search conditions: DAY=bDAY eDAY */ if( (image_cyd < bdate) || (image_cyd > edate) ) continue; tprintf(trace_string, "%s PASS DAY CHECK = %d", server, image_cyd ); /* Check client search conditions: TIME=bTIME eTIME */ if( (image_hms < btime) || (image_hms > etime) ) continue; tprintf(trace_string, "%s PASS TIME CHECK = %d", server, image_hms ); /* Multi-band transfer of L2 data is NOT permitted */ MultiBandL2_flag = 0; if( (sss[image_dataset_position-1] == 187 || sss[image_dataset_position-1] == 189 || sss[image_dataset_position-1] == 191 || sss[image_dataset_position-1] == 193) && MultiBand_Nmap > 1 ) { tprintf(trace_string, "%s SSS=%d Multi=%d", server, sss[image_dataset_position-1], MultiBand_Nmap); tprintf(trace_string, "%s Multiband request ...BUT... Image is L2 --> NOT ALLOWED", server); MultiBandL2_flag = 1; continue; } /* Highest_resolution= 4; */ Nfound = 0; lowest_resolution = 0; highest_resolution= 999; band_nav = 0; tprintf(trace_string, "%s NOBAND_SPECIFIED=%d ALLBANDS=%d ALLSIZE=%d",server,NOBAND_SPECIFIED,ALLBANDS,ALLSIZE); for( i=0; i= lowest_resolution ) { lowest_resolution = iress[image_dataset_position-1][image_band-1]; band_nav = image_band; } if( this_resolution <= highest_resolution ) { highest_resolution = iress[image_dataset_position-1][image_band-1]; band_alloc = image_band; } } } } /* User did specify a Band. Check client search conditions: BAND=band ... */ } else { tprintf(trace_string, "%s band(s) specified", server); for( i=0; i= lowest_resolution ) { lowest_resolution = iress[image_dataset_position-1][image_band-1]; band_nav = image_band; } if( this_resolution <= highest_resolution ) { highest_resolution = iress[image_dataset_position-1][image_band-1]; band_alloc = image_band; } } } if( Nfound != request_n_bands ) continue; tprintf(trace_string, "%s Found all requested bands", server); tprintf(trace_string, "%s LOWEST RESOLUTION = %d ", server,lowest_resolution); /* Compute the sampling for each band in the request */ for( i=0; i get NetCDF handles for each */ for( iband=0; iband>>>> */ rc = nc_get_var_short( ncdf_ids[band_nav-1], var_id, Yarray ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s READ FAILED for variable=y", server); } else { image_ul_line = (int) Yarray[0]; /* <<<<< UPC mod 20181220 >>>>> */ } /* Free y variable memory */ free (Yarray); tprintf(trace_string,"%s SECOND PASS: Yarray freed",server); } } /* Get x dimension */ image_elems[0] = -9999; rc = nc_inq_dimid( ncdf_ids[band_nav-1], "x", &dim_id ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the element dimension", server); } else { rc = nc_inq_dimlen( ncdf_ids[band_nav-1], dim_id, &cells ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the element dimension", server); } else { image_elems[0] = (int) cells; } } tprintf(trace_string, "%s X=%ld", server, cells ); /* Open the x variable */ cfac[band_nav-1] = -9999.0; coff[band_nav-1] = -9999.0; rc = nc_inq_varid(ncdf_ids[band_nav-1],"x",&var_id); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the element scale factor", server); } else { rc = nc_get_att_float( ncdf_ids[band_nav-1], var_id, "scale_factor", &cfac[band_nav-1]); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the element scale factor", server); } rc = nc_get_att_float( ncdf_ids[band_nav-1], var_id, "add_offset", &coff[band_nav-1]); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the element add offset", server); } /* malloc memory for x variable */ Xarray = malloc( image_elems[0] * sizeof(short) ); tprintf(trace_string,"%s SECOND PASS: Xarray malloced",server); if( Xarray != NULL ) { image_ul_element = -9999; /* <<<<< UPC mod 20181220 >>>>> */ rc = nc_get_var_short( ncdf_ids[band_nav-1], var_id, Xarray ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s READ FAILED for variable=x", server); } else { image_ul_element = (int) Xarray[0]; /* <<<<< UPC mod 20181220 >>>>> */ } /* Free x variable memory */ free (Xarray); tprintf(trace_string,"%s SECOND PASS: Xarray freed",server); } } tprintf(trace_string, "%s loff[band_nav-1]=%f coff[band_nav-1]=%f", server, loff[band_nav-1], coff[band_nav-1] ); tprintf(trace_string, "%s lfac[band_nav-1]=%f cfac[band_nav-1]=%f", server, lfac[band_nav-1], cfac[band_nav-1] ); tprintf(trace_string, "%s image_ul_line=%d image_ul_element=%d", server, image_ul_line, image_ul_element ); /* ** <<<<< UPC add 20181227 >>>>> ** Adjust line and element offsets to account for products whose X and Y ** dimenions values do not range from 0 - max[XY] */ loff[band_nav-1] = lfac[band_nav-1] * image_ul_line + loff[band_nav-1]; coff[band_nav-1] = cfac[band_nav-1] * image_ul_element + coff[band_nav-1]; tprintf(trace_string, "%s loff[band_nav-1]=%f coff[band_nav-1]=%f", server, loff[band_nav-1], coff[band_nav-1] ); tprintf(trace_string, "%s lfac[band_nav-1]=%f cfac[band_nav-1]=%f", server, lfac[band_nav-1], cfac[band_nav-1] ); /* Open the nominal satellite subpoint lat variable */ ssp_lat = -9999.0; if ( CalType == SCMI ) { rc = nc_get_att_float( ncdf_ids[band_nav-1], NC_GLOBAL, "satellite_latitude", &ssp_lat ); } else { rc = nc_inq_varid(ncdf_ids[band_nav-1],"nominal_satellite_subpoint_lat",&var_id ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the satellite latitude subpoint", server); } else { rc = nc_get_var_float( ncdf_ids[band_nav-1], var_id, &ssp_lat ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the nominal latitude subpoint", server); } } } if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the satellite latitude subpoint", server); } /* Open the nominal satellite subpoint lon variable */ ssp_lon = -9999.0; if ( CalType == SCMI ) { rc = nc_get_att_float( ncdf_ids[band_nav-1], NC_GLOBAL, "satellite_longitude", &ssp_lon ); } else { rc = nc_inq_varid( ncdf_ids[band_nav-1], "nominal_satellite_subpoint_lon", &var_id ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the satellite longitude subpoint", server); } else { rc = nc_get_var_float( ncdf_ids[band_nav-1], var_id, &ssp_lon ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the nominal longitude subpoint", server); } } } if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the satellite longitude subpoint", server); } /* -------------- WCS3 ----------- */ /* Open the projection information variable */ pro_lon = -9999.0; if ( CalType == SCMI ) { rc = nc_inq_varid( ncdf_ids[band_nav-1], "fixedgrid_projection", &var_id ); } else { rc = nc_inq_varid( ncdf_ids[band_nav-1], "goes_imager_projection", &var_id ); } if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the projection information", server); } else { rc = nc_get_att_float(ncdf_ids[band_nav-1], var_id, "longitude_of_projection_origin", &pro_lon); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the projection longitude subpoint", server); } } /* -------------- WCS3 ----------- */ /* Get the resolution of the image band */ image_line_base_resolution = iress[image_dataset_position-1][band_nav-1]; image_element_base_resolution = iress[image_dataset_position-1][band_nav-1]; image_geo_latitude = ssp_lat; image_geo_longitude = ssp_lon; image_element_size = elems[image_dataset_position-1][band_nav-1]; image_line_size = lines[image_dataset_position-1][band_nav-1]; image_data_size = 2; image_n_bands = request_n_bands; /* tprintf(trace_string, "%s IMAGE_LINE_BASE_RES=%d",server, image_line_base_resolution); */ /* tprintf(trace_string, "%s IMAGE Lines=%d Elems=%d",server, image_line_size, image_element_size); */ /* tprintf(trace_string, "%s IMAGE ssp_Lat=%f ssp_Lon=%f pro_lon=%f",server, ssp_lat, ssp_lon, pro_lon); */ /* Image starting coordinates */ image_starting_line = 1; image_starting_element = 1; /* go here if database */ BYPASS: /* Reserve memory for the reading the source images. This size is based on the line size (number of elements) of the highest resolution band */ SAMPLE_size = elems[image_dataset_position-1][band_alloc-1]; /* tprintf(trace_string, "%s POS = %d",server,image_dataset_position); */ /* tprintf(trace_string, "%s BAND = %d",server,band_alloc); */ /* tprintf(trace_string, "%s SIZE = %d",server,SAMPLE_size); */ /* Increment the number of bands found */ found_n_bands = request_n_bands; 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_REQUEST */ /* tprintf(trace_string,"%s GEO REQUEST",server); */ /* Determine the size of the geo request */ read_geo_line_size = image_line_size; read_geo_element_size = image_element_size; /* Determine the coordinates of the geo request */ read_geo_starting_line = 0; read_geo_starting_element = 0; read_geo_ending_line = read_geo_starting_line + read_geo_line_size - 1; read_geo_ending_element = read_geo_starting_element + read_geo_element_size - 1; tprintf(trace_string,"%s READ GEO: line size=%d",server,read_geo_line_size); tprintf(trace_string,"%s READ GEO: element size=%d",server,read_geo_element_size); tprintf(trace_string,"%s READ GEO: starting line=%d",server,read_geo_starting_line); tprintf(trace_string,"%s READ GEO: starting element=%d",server,read_geo_starting_element); tprintf(trace_string,"%s READ GEO: ending line=%d",server,read_geo_ending_line); tprintf(trace_string,"%s READ GEO: ending element=%d",server,read_geo_ending_element); /* ************************************************************************* ** Step 9: Transfer starts here ** ** Construct and send the following blocks: ** DIRECTORY ** NAVIGATION ** CALIBRATION ** AUXILLARY ** DATA ** *************************************************************************** */ /* tprintf(trace_string,"%s TRANSFER",server); */ /* Size of the line prefix */ psize = 0; if( request_n_bands > 1 ) { psize = request_n_bands / 4; if( (request_n_bands % 4) != 0 ) psize = psize+1; psize = psize * 4; } /* tprintf(trace_string,"%s PREFIX size=%d",server,psize); */ /* 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 ); /* tprintf(trace_string,"%s DATA size=%d",server,dat_block_size); */ /* 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); /* tprintf(trace_string,"%s total_block_size=%d",server,totalSize); */ requestBlock.reply_length += totalSize; M0swbyt4(&totalSize, 1); rc = M0sxsend(4, &totalSize ); tprintf(trace_string,"%s **************** SATELLITE =%d",server, sss[image_dataset_position-1] ); tprintf(trace_string,"%s **************** VAR =%s", server, var_name[0]); /* ***************** DIRECTORY BLOCK ****************** */ /* Initialize the directory block */ for( i=0; i>>>> */ directory[18] = directory[18] + abiband.lBand[0]; /* <<<<< UPC mod 20181220 >>>>> */ directory[19] = directory[19] + abiband.lBand[1]; /* <<<<< UPC mod 20181220 >>>>> */ } /* Modify for multi-band transfer */ if( request_n_bands > 1 ) { directory[14] = psize; directory[50] = psize; for( i=0; i 0 ) { chunkp = (size_t *) malloc(sizeof(size_t) * (VAR_ndims[image_band-1] + 1)); chunk_size = 100 * 2; rc = nc_inq_var_chunking( ncdf_ids[image_band-1], var_ids[image_band-1], NULL, chunkp ); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read chunkp", server); chunk_size *= 1024 * 1024; } else { for( k=0; k 1 ) { memcpy( (void *)&uchar_array[0], (void *)&level_map[0], psize ); } } else if( space == 2 ) { OUTSIZE = (psize/2) + (request_n_bands*request_element_size); ushort_array=calloc(OUTSIZE,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 ); } } else if( space == 4 ) { OUTSIZE = (psize/4) + (request_n_bands*request_element_size); ulong_array=calloc(OUTSIZE,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 ); } } tprintf(trace_string, "%s space=%d, OUTSIZE=%d, psize=%d",server,space,OUTSIZE,psize); /* IMAGE LINE LOOP */ iBand = request_bands[0]; currentOpn = 0; init_line = 0; init_elem = 0; /* Only do this for single bands. Multibands can only transfer RAW data */ if( MultiBand_flag == 0 ) { /* Get the principle variable id */ if( rc != NC_NOERR ) { tprintf(trace_string, "%s Did not find the %s variable", server, var_name[0]); } else { rc = nc_get_att_float( ncdf_ids[image_band-1], var_ids[image_band-1], "scale_factor", &VAR_scale[image_band-1]); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the band scale factor", server); } rc = nc_get_att_float( ncdf_ids[image_band-1], var_ids[image_band-1], "add_offset", &VAR_offset[image_band-1]); if( rc != NC_NOERR ) { tprintf(trace_string, "%s Could not read the band add offset", server); } } /* Initialize the calibration */ rc = ( CalType == SCMI ) ? kbprep_(&ONE,"SCMI") : kbprep_(&ONE,"ABIN"); if( rc == -1 ) { (void)strcpy(requestBlock.errormsg, "Failed to Prep the Calibration"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } /* tprintf(trace_string,"%s request_data_size=%d", server,space); */ options[0] = PIXBYTE; options[1] = 4; options[2] = sss[image_dataset_position-1]; options[3] = request_bands[0]; rc = kb1ini_("RAW ", &directory[52], options, 4, 4); if( rc == -1 ) { (void)strcpy(requestBlock.errormsg, "Failed to Initialize the Calibration 1"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } else { options[0] = band; rc = kb1opt_("CALB", cal_block, options_out, 4); if (rc == -1) { (void)strcpy(requestBlock.errormsg, "Failed to Initialize the Calibration 2"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } if( strncmp( unit, "BRIT",4 ) == 0 && strncmp( csstr, "EXP" ,3) == 0) { options[0] = band; options[1] = sss[image_dataset_position-1]; options[2] = 1; tprintf(trace_string,"%s options=%d %d ", server,options[0], options[1]); rc = kb1opt_("STR ", options, options_out, 4); tprintf(trace_string,"%s kb1opt return=%d ", server,rc); if(rc == 0) { directory[EXP_BRIT_FLAG] = 1; memcpy(&directory[EXP_BRIT_NAME1], options_out, 8); } } /* tprintf(trace_string, "%s PASSED: Calibration init", server); */ } /* Send the directory to client */ M0swbyt4( &directory[ 0], 20 ); M0swbyt4( &directory[21], 3 ); M0swbyt4( &directory[32], 19 ); M0swbyt4( &directory[53], 2 ); M0swbyt4( &directory[58], 6 ); if( ischar_(&directory[20]) == 0) M0swbyt4(&directory[20], 1); rc = M0sxsend( DIR_SIZE*4, directory ); M0swbyt4( &directory[ 0], 20 ); M0swbyt4( &directory[21], 3 ); M0swbyt4( &directory[32], 19 ); M0swbyt4( &directory[53], 2 ); M0swbyt4( &directory[58], 6 ); if( ischar_(&directory[20]) == 0) M0swbyt4(&directory[20], 1); /* tprintf(trace_string, "%s sent directory: bytes=%d", server,DIR_SIZE*4); */ /* Send the navigation */ M0swbyt4( &nav_block[1], NAV_BLOCK_SIZE-1 ); rc = M0sxsend( NAV_BLOCK_SIZE*4, nav_block ); /* tprintf(trace_string, "%s sent navigation: bytes=%d", server,NAV_BLOCK_SIZE*4); */ /* Send the calibration */ M0swbyt4( &cal_block[1], CAL_BLOCK_SIZE-1 ); rc = M0sxsend( CAL_BLOCK_SIZE*4, cal_block ); M0swbyt4( &cal_block[1], CAL_BLOCK_SIZE-1 ); /* IMAGE LINE LOOP */ /* tprintf(trace_string, "%s START SENDING THE DATA type=%d",server,ounit_flag); */ tprintf(trace_string, "%s read_starting_element=%d",server,read_starting_element); tprintf(trace_string, "%s read_ending_element=%d",server,read_ending_element); tprintf(trace_string, "%s request_element_magnification=%d",server,request_element_magnification); for( i=read_starting_line; i<=read_ending_line; i=i+request_line_magnification ) { /* IMAGE BAND LOOP */ for( k=0; k=0 && iline output units */ if( strncmp( unit, "RAW",3 ) != 0 ) { rc = kb1cal_( prefix, directory, &SAMPLE_size, &band, Wrd_array ); if( rc == -1 ) { (void)strcpy(requestBlock.errormsg, "FAILED Line Calibration"); requestBlock.returncode = -30; M0sxdone(&requestBlock); return(0); } } } else { (void) memset(Cnt_array, INVALID_VALUE, sizeof(short)*SAMPLE_size); (void) memset(Wrd_array, INVALID_VALUE, sizeof(int)*SAMPLE_size); } /* At this point you have a line of data for a particular band. Read the data based on the requested magnification and insert the elements into the output line array based on the number of bands */ /* IMAGE ELEMENT LOOP */ indx = k + psize/2; for( j=read_starting_element; j<=read_ending_element; j=j+request_element_magnification ) { /* Only send valid elements */ value = 0; jelem = j*einc; if( jelem>=0 && jelem 1 ) { memcpy( (void *)&uchar_array[0], (void *)&level_map[0], psize ); } } else if( space == 2 ) { rc = M0sxsend( size*sizeof(short), ushort_array ); (void) memset(ushort_array, INVALID_VALUE, size*sizeof(short)); if( request_n_bands > 1 ) { memcpy( (void *)&ushort_array[0], (void *)&level_map[0], psize ); } } else if( space == 4 ) { rc = M0sxsend( size*sizeof(int), ulong_array ); (void) memset(ulong_array, INVALID_VALUE, size*sizeof(int)); if( request_n_bands > 1 ) { memcpy( (void *)&ulong_array[0], (void *)&level_map[0], psize ); } } /* tprintf(trace_string, "%s Sent Line = %d ",server,i+1); */ } /* ***************** House Keeping **************** */ /* CLOSE the NCDF file(s) */ for( i=0; i