#include #include #include #include #include // Added by Zhang Yi on 2021-08-26 #include #include "../lib/constants.h" #include "../lib/parsers.h" #include "../lib/linalg.h" #define MAX_GRID_POINTS 50000 #define GRID_FORMAT "%lf %lf %f %lf" #if defined(_MSC_VER) /* Added for windows by Yi Zhang on 2021-08-26*/ #include typedef SSIZE_T ssize_t; #endif // TODO conversion of input/output units nT/km pT/km nT/m pT/m void printcomp(double* longitudes, double* latitudes, double* values, int n_values) { for (int h = 0; h < n_values; h++) printf("%lf %lf %lf\n", longitudes[h], latitudes[h], values[h]); return; } void printall(double* longitudes, double* latitudes, int n_values, double* values1, double* values2, double* values3, double* values4, double* values5, double* values6, double* values7) { for (int h = 0; h < n_values; h++) printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf\n", longitudes[h], latitudes[h], values1[h], values2[h], values3[h], values4[h], values5[h], values6[h], values7[h]); return; } void print_gradcalc_help(const char *progname) { printf("MAGNETIC TESSEROIDS: Gradient Calculator\n"); printf("Usage: %s [OPTIONS]\n\n", progname); printf("Options:\n"); printf("\t-h\t\t\t Help\n\n"); printf("\t-bx[GRID FILENAME]\t Grid filename with Bx component\n"); printf("\t-by[GRID FILENAME]\t Grid filename with By component\n"); printf("\t-bz[GRID FILENAME]\t Grid filename with Bz component\n"); printf("\tNOTE:\tall grids must be in format LON LAT ALT B*,\n\t\tstart from West-South corner and longitudes must increment first.\n\t\tLON, LAT in [deg], B* in [nT] and ALT in [m].\n\n"); printf("\t-c[COORD SYSTEM]\t Coordinate system in input grids. 1 - North-East-Down, 2 - North-East-Up\n"); printf("\t-o[COMPONENT]\t\t If 0, then output format is LON LAT BXX BYX BZX BXY BYY BZY BZZ, if 1-7, then \n"); printf("\tonly corresponding component would be printed with format LON LAT B**.\n"); printf("\tNOTE: output is always in North-East-Down coordinate system.\n\t\tLON, LAT in [deg], B** in [nT/km].\n"); //printf("TODO\n"); } int main(int argc, char**argv) { const char * progname = "tessutil_gradient_calculator"; GRADCALC_ARGS args; int rc; //log_init(LOG_INFO); rc = parse_gradcalc_args(argc, argv, progname, &args, &print_gradcalc_help); if(rc == 2) //help { return 0; } if(rc == 1) { printf("Terminating due to bad input\n"); printf("Try '%s -h' for instructions\n", progname); return 1; } if ((args.gridbx_set == 0) || (args.gridbx_set == 0) || (args.gridbx_set == 0)) { printf("no input grids\n"); exit(EXIT_FAILURE); } if (args.bz_NEU_NED == 1) printf("#Coordinate system in input grids: North-East-Down\n"); else printf("#Coordinate system in input grids: North-East-Up\n"); printf("#Coordinate system in output grid: North-East-Down\n"); double lons[MAX_GRID_POINTS]; double lats[MAX_GRID_POINTS]; float alts[MAX_GRID_POINTS]; double bx[MAX_GRID_POINTS]; double by[MAX_GRID_POINTS]; double bz[MAX_GRID_POINTS]; //read file with bx //char * line = NULL; std::string line; size_t len = 0; ssize_t read; //FILE * bxfp = fopen(args.gridbx_fn, "r"); //if (bxfp == NULL) std::ifstream bxfp(args.gridbx_fn, std::ios::in); // Updated by Yi Zhang on 2021-08-26 if (!bxfp) { printf("ERROR: Can not open file with Bx values.\n"); exit(EXIT_FAILURE); } int n_lines = 0; //while ((read = getline(&line, &len, bxfp )) != -1) while (getline(bxfp, line)) { //if ((line[0] != '#') && (strlen(line) > 2)) if ((line[0] != '#') && (line.length() > 2)) { n_lines++; if (n_lines>MAX_GRID_POINTS) { printf("ERROR: Too many grid points (> %d) in the input. Recompile program with a bigger value of MAX_GRID_POINTS.\n", n_lines); exit(EXIT_FAILURE); } sscanf(line.c_str(), GRID_FORMAT, &lons[n_lines-1], &lats[n_lines-1], &alts[n_lines-1], &bx[n_lines-1]); } } //fclose(bxfp); bxfp.close(); /*number of grid points*/ printf("#Number of grid points: %d\n", n_lines); /*grid spacing*/ double lon_min = lons[0]; double lon_max = lons[n_lines-1]; double lon_step = lons[1]-lons[0]; if ((lon_step == 0) || (lon_step <= 0) || (lon_max < lon_min)) { printf("ERROR: Wrong grid format. Longitudes must increment first. Use the format of tessgrd.\n"); exit(EXIT_FAILURE); } int lon_n = 1; while ((lats[lon_n] == lats[0]) && (lon_n < n_lines)) { lon_n++; } double lat_step = lats[lon_n]-lats[0]; int lat_n = n_lines / lon_n; double lat_min = lats[0]; double lat_max = lats[n_lines-1]; if ((lat_step <= 0) || (lat_step <= 0) || (lat_max < lat_min)) { printf("ERROR: Wrong grid format. Latitudes must increment. Use the format of tessgrd.\n"); exit(EXIT_FAILURE); } printf("#Longitudinal step: %lf, latitudinal step: %lf \n", lon_step, lat_step); printf("#Longitudinal points: %d, latitudinal points: %d \n", lon_n, lat_n); printf("#Edges: W %lf, E %lf, S %lf, N %lf \n", lon_min, lon_max, lat_min, lat_max); /* read other grids */ // By //FILE * byfp = fopen(args.gridby_fn, "r"); //if (byfp == NULL) std::ifstream byfp(args.gridby_fn, std::ios::in); if (!byfp) { printf("ERROR: Can not open file with Bx values.\n"); exit(EXIT_FAILURE); } int n_lines2 = 0; //while ((read = getline(&line, &len, byfp )) != -1) while (getline(byfp, line)) { //if ((line[0] != '#') && (strlen(line) > 2)) if ((line[0] != '#') && (line.length() > 2)) { n_lines2++; //printf("%s", line); double dummy1, dummy2; float dummy3; sscanf(line.c_str(), GRID_FORMAT , &dummy1, &dummy2, &dummy3, &by[n_lines2-1]); } } //fclose(byfp); byfp.close(); if (n_lines2 != n_lines) { printf("ERROR: Grid points of Bx and By do not coincide.\n"); exit(EXIT_FAILURE); } // Bz //FILE * bzfp = fopen(args.gridbz_fn, "r"); //if (bzfp == NULL) std::ifstream bzfp(args.gridbz_fn, std::ios::in); if (!bzfp) { printf("ERROR: Can not open file with Bx values.\n"); exit(EXIT_FAILURE); } n_lines2 = 0; //while ((read = getline(&line, &len, bzfp )) != -1) while (getline(bzfp, line)) { if ((line[0] != '#') && (line.length() > 2)) { n_lines2++; //printf("%s", line); double dummy1, dummy2; float dummy3; double bz_curr; sscanf(line.c_str(), GRID_FORMAT, &dummy1, &dummy2, &dummy3,&bz_curr); bz[n_lines2-1] = args.bz_NEU_NED* bz_curr; //COORDINATE SYSTEM NEU or NED } } //fclose(byfp); byfp.close(); if (n_lines2 != n_lines) { printf("ERROR: Grid points of Bx and Bz do not coincide.\n"); exit(EXIT_FAILURE); } /* calculate gradients */ double bxx[MAX_GRID_POINTS]; double byx[MAX_GRID_POINTS]; double bzx[MAX_GRID_POINTS]; double bxy[MAX_GRID_POINTS]; double byy[MAX_GRID_POINTS]; double bzy[MAX_GRID_POINTS]; double bzz[MAX_GRID_POINTS]; int cent_ind, west_ind, east_ind, south_ind, north_ind; for (int i = 1; i