#include #include #include #include #include #include #include #include #include #include #include #include #include /* Macro definitions */ /* Version information of the tool. It consists of: * Major version: increases whenever there are major feature changes; * Minor version: increases whenever there are feature changes; * Release: increases whenever officially released. */ #define NAGG_VER_MAJOR 1 #define NAGG_VER_MINOR 3 #define NAGG_VER_RELEASE 1 #define NAGG_VER_SUBRELEASE "pre1" #define NAGG_RELEASE_DATE "currently under development" #define NAGG_VERSION_FORMAT_STRING "HDF NPP Aggregation version %d.%d.%d%s, %s" /*Granule macro definitions */ #define NAGG_Product_Type_size 63 /* up to 63 chars long */ #define NAGG_Granule_ID_size 15 /* Satellite 3 bytes, */ /* 10 microsec: 12 bytes */ /* Total 15 bytes */ #define NAGG_GRANVER_size 15 /* Granule version info size */ #define NAGG_DATE_size 8 /* Granule date info size */ #define NAGG_TIME_size 14 /* Granule time info size */ #define NAGG_Granule_info_max 10000 /* Max number of granules managed */ #define NAGG_Product_list_max 30 /* Max number of products requested */ #define NAGG_outputfiles_max 30 /* Max number of output file hames */ #define NPP_Product_max 96 /* Max number of NPP Products */ #define NPP_Geo_Location_max 19 /* Max number of NPP Geolocations products */ #define NAGG_Granules_selected_max 500 /* Max number of granules selected */ /* to output */ /* NPP data product file name struct */ #define DPID_size 5 /* DPID name size */ #define DPID_NUM_MAX 30 /* max number of DPIDs */ #define SPACECRAFT_size 3 /* Spacecraft ID */ #define Data_date_size 8 /* Date: YYYYMMDD */ #define Data_time_size 7 /* Time: HHMMSSS */ #define Orbit_number_size 5 /* Orbit: nnnnn */ #define Creation_date_size 20 /* Creation Date: YYYYMMDDHHMMSSssssss */ #define Origin_size 4 /* Origin: XXXX */ #define Domain_size 3 /* Domain: XXX */ /* file name convension * -...-__d_t_e \ * _b_c__.h5 */ /* Add 1 to DPID_NUM_MAX to account for the possible Geolocation product ID. * The other plus 1 is for the hyphens or underscores. * The last 3 is for ".h5". */ #define NPPFileName_size_max \ ((DPID_size+1)*(DPID_NUM_MAX+1) + (SPACECRAFT_size+1) + \ (1+Data_date_size+1) + (1+Data_time_size+1) + (1+Data_time_size+1) + \ (1+Orbit_number_size+1) + (1+Creation_date_size+1) + \ (Origin_size+1) + (Domain_size) + 3) #define Time_First_Ascend (1300968033000000LL) #define million_microsec 1000000 /* one million microsec = 1 sec */ #define micros2s(s) (s/1e6) /* microseconds to seconds */ /* * Status return values. * Since some unix/c routines use 0 and -1 (or more precisely, non-negative * vs. negative) as their return code, and some assumption had been made in * the code about that, it is important to keep these constants the same * values. When checking the success or failure of an integer-valued * function, remember to compare against the zero which represents success. */ #define SUCCEED 0 #define FAIL (-1) /* Exit code. Recall that Unix exit code is defined as an unsigned by::te, * therefore, adhere to the range of 0-127. By convention, 128-255 are * for exit codes resulted from signals. Best to stay from 0 (success) to * non-zero 1 digit (failure). */ #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 /* Logic values. C uses 0 for false and non-0 for true. */ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE !FALSE #endif /* Macros for functions (these macros may become real function if it gets */ /* more complex. */ #define get_option_debug (debug_arg) /* Global types declaration. */ typedef unsigned long long iet_t; /* Geolocation file criterion */ typedef enum geolocation_t { GEOFILE_NO, /* no need for geolocation granules */ GEOFILE_YES, /* approximate matching of geolocation input file */ GEOFILE_STRICT, /* exact matching of geolocation input files */ GEOFILE_GEOPRODUCT /* a Geoproduct ID is given */ } geolocation_t; /* Output File Formats */ typedef enum outfileformat_t { PACKAGED, /* all products including geo-product are in 1 file */ UNPACKAGED /* each product in 1 file */ } outfileformat_t; /* Forward declaration */ typedef struct granule_t granule_t; typedef struct granule_pattern_t granule_pattern_t; /* * Information of a granule. * char array size is "+1" for the null terminator.. */ struct granule_t { char product_id[DPID_size+1]; /* product ID */ char product_name[NAGG_Product_Type_size+1]; /* product name */ int granule_input_index; /* index of granule dataset in input file */ char granule_id[NAGG_Granule_ID_size+1]; /*granule ID */ char granule_version[NAGG_GRANVER_size+1]; /*granule version */ int granule_version_number; /*granule version number *derived from granule *version: N/A=>-1, An=>n */ iet_t granule_start_time_IET; /*granule start time. micro-sec since 1958 jan 1. */ iet_t granule_end_time_IET; /*granule end time */ char beginning_date[NAGG_DATE_size+1]; /*granule beginning date */ char beginning_time[NAGG_TIME_size+1]; /*granule beginning time */ char ending_time[NAGG_TIME_size+1]; /*granule ending time */ uint64_t orbit_number; /*orbit number */ const char *geofile; /*geolocation filename */ const char *file_in; /*file in which the granule is */ }; typedef granule_t* granule_p_t; /* granule Pointer Type */ /* * Information needed to write a fill granule. One structure is created for * each product and the geoproduct. This structure is expected to change if * compression is added. */ struct granule_pattern_t { char product_id[DPID_size+1]; /* product ID */ char product_name[NAGG_Product_Type_size+1]; /* product name */ char geofile[NPPFileName_size_max+1]; /*geolocation filename */ char file_in[NPPFileName_size_max+1]; /*file in which the granule is */ }; typedef granule_pattern_t* granule_pattern_p_t; /* granule pattern pointer type */ /* structure that holds information to compose a new NPP product file name */ struct nppfileinfo_t { int nproduct_id; /* number of products in the file */ char product_id_list[DPID_NUM_MAX][DPID_size]; char geolocation_id[DPID_size]; char *spacecraft; char *Start_date; char Start_time[Data_time_size]; char Stop_time[Data_time_size]; char Orbit_number[Orbit_number_size]; char Creation_date[Creation_date_size]; char *Origin; char *Domain; }; typedef struct nppfileinfo_t nppfileinfo_t; typedef nppfileinfo_t* nppfileinfo_p_t; /* pointer to an nppfileinfo_t */ /* structure that holds the information of a product in the products tables */ struct nppproduct_t { char *DPID; /* Data Product ID */ char *sname; /* short name */ iet_t duration; /* granule nominal duration */ /* 0 means undefined. */ char *GPID; /* Geolocation product ID used by this product */ /* NULL means undefined as the case for Geolocation products */ }; typedef struct nppproduct_t nppproduct_t; typedef nppproduct_t* nppproduct_p_t; /* pointer to an nppproduct_t */ typedef char NPPFileName_t[NPPFileName_size_max+1]; /* NULL terminated */ typedef NPPFileName_t* NPPFileName_p_t; /* Global variables declaration. */ /* Option flags & parameters */ extern int ngranulesperfile; extern char **products_list; extern int nproducts; extern char *outDir; extern char *origin_arg; extern char *domain_arg; extern char **inputfiles; extern int ninputfiles; extern char *geoproduct; extern geolocation_t geofiles_arg; extern outfileformat_t outfileformat; extern int debug_arg; /* Granule Information variables */ /* array to hold all granules found in input files*/ extern granule_p_t granule_info_array[NAGG_Granule_info_max]; /* array to hold all products requested. */ extern char *products_list_array[NAGG_Product_list_max]; /* array to hold output file names */ extern char *outputfiles_array[NAGG_outputfiles_max]; /* array to hold all NPP product names */ extern nppproduct_t product_table[NPP_Product_max]; extern nppproduct_t geolocation_table[NPP_Geo_Location_max]; /* array to hold a granule pattern for each product */ /* size is maximum number of products + 1 GEO product */ extern granule_pattern_p_t granule_pattern_array[NAGG_Product_list_max + 1]; /* other global variables */ extern const char *progname_g; /* program name */ /* Prototypes */ int parse_options(int argc, char * const argv[]); int nagg_get_granules(char **file_list, int number_of_files, char **products_list, int nproducts, geolocation_t geofiles_arg, char *geoproduct, granule_p_t *granule_info_p[], int *number_of_granules_p); granule_pattern_p_t get_granule_pattern(const char *product_id); void nagg_print_granules(granule_p_t granArr[], int number_of_granules); void nagg_sort_granules(granule_p_t granule_info_p[], int number_of_granules); char * get_product_sname_by_id(const char *prod_id); char * get_product_id_by_sname(const char *prod_sname); char * get_gpid_by_id(const char *prod_id); const char * get_outdir(void); iet_t get_product_duration_by_id(const char *prod_id); void print_product_lists(void); int start_write(NPPFileName_t *outfiles, int noutfiles, const char *outgeofile, char *geoproduct, char **products_list, int nproducts, const char *creationdate, const char *creationtime, int ngranulesperfile); int write_granules(granule_p_t granule, int i_granule); int end_write(void); int compose_output_fname(granule_p_t selected_granules[], int number_of_granules, char **products_list, int nproducts, char *geoproduct, int ngranulesperfile, outfileformat_t outfileformat, int *_noutfiles, NPPFileName_t output_fname[], char **geo_fname, char *creationdate); int select_granules(granule_p_t granule_info[], int *gindex, char **products_list, int nproducts, int total_nproducts, char *geoproduct, granule_p_t granules_selected[], int ngranulesperfile, int *granules_remain, int *total_granules_file); int nagg_report(const char *outfile, int ngranules); void leave(int ret); void usage(void); void print_product_lists(void);