194 lines
5.6 KiB
C
194 lines
5.6 KiB
C
/*
|
|
Calculate the mass of a tesseroid model.
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include "../lib/version.h"
|
|
#include "../lib/parsers.h"
|
|
#include "../lib/logger.h"
|
|
#include "../lib/geometry.h"
|
|
|
|
|
|
/** Print the help message */
|
|
void print_help()
|
|
{
|
|
printf("Usage: tessmass TESSFILE [OPTIONS]\n\n");
|
|
printf("Calculate the mass of a tesseroid model.\n\n");
|
|
printf("All units either SI or degrees!\n\n");
|
|
printf("Input:\n");
|
|
printf(" If TESSFILE is omited, will read from standard input (stdin)\n");
|
|
printf(" TESSFILE: File containing the tesseroid model\n");
|
|
printf(" * Each tesseroid is specified by the values of its borders\n");
|
|
printf(" and density\n");
|
|
printf(" * The file should contain one tesseroid per line\n");
|
|
printf(" * Each line should have the following column format:\n");
|
|
printf(" West East South North Top Bottom Density\n");
|
|
printf(" * Top and Bottom should be read as 'depth to top' and \n");
|
|
printf(" 'depth to bottom' from the mean Earth radius. Use negative\n");
|
|
printf(" values if above the surface, for example when modeling\n");
|
|
printf(" topography\n");
|
|
printf(" * If a line starts with # it will be considered a comment\n");
|
|
printf(" and will be ignored\n\n");
|
|
printf("Output:\n");
|
|
printf(" Printed to standard output (stdout) in same units as input\n\n");
|
|
printf("Options:\n");
|
|
printf(" -rLOW/HIGH Only take into account tesseroids with\n");
|
|
printf(" density between LOW and HIGH\n");
|
|
printf(" -h Print instructions.\n");
|
|
printf(" --version Print version and license information.\n");
|
|
printf(" -v Enable verbose printing to stderr.\n");
|
|
printf(" -lFILENAME Print log messages to file FILENAME.\n");
|
|
print_copyright();
|
|
}
|
|
|
|
|
|
/** Main */
|
|
int main(int argc, char **argv)
|
|
{
|
|
char *progname = "tessmass";
|
|
TESSMASS_ARGS args;
|
|
TESSEROID tess;
|
|
double mass = 0;
|
|
int rc, line, size = 0, error_exit = 0, bad_input = 0;
|
|
FILE *logfile = NULL, *modelfile = NULL;
|
|
time_t rawtime;
|
|
struct tm * timeinfo;
|
|
char buff[10000];
|
|
|
|
log_init(LOG_INFO);
|
|
|
|
rc = parse_tessmass_args(argc, argv, progname, &args, &print_help);
|
|
if(rc == 2)
|
|
{
|
|
return 0;
|
|
}
|
|
if(rc == 1)
|
|
{
|
|
log_warning("Terminating due to bad input");
|
|
log_warning("Try '%s -h' for instructions", progname);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Set the appropriate logging level and log to file if necessary */
|
|
if(!args.verbose)
|
|
{
|
|
log_init(LOG_WARNING);
|
|
}
|
|
if(args.logtofile)
|
|
{
|
|
logfile = fopen(args.logfname, "w");
|
|
if(logfile == NULL)
|
|
{
|
|
log_error("unable to create log file %s", args.logfname);
|
|
log_warning("Terminating due to bad input");
|
|
log_warning("Try '%s -h' for instructions", progname);
|
|
return 1;
|
|
}
|
|
log_tofile(logfile, LOG_INFO);
|
|
}
|
|
|
|
/* Print standard verbose */
|
|
log_info("%s (Tesseroids project) %s", progname, tesseroids_version);
|
|
time(&rawtime);
|
|
timeinfo = localtime(&rawtime);
|
|
log_info("(local time) %s", asctime(timeinfo));
|
|
|
|
/* If an input file is not given, read from stdin. Else open the file */
|
|
if(rc == 3)
|
|
{
|
|
log_info("Reading tesseroids from stdin");
|
|
modelfile = stdin;
|
|
}
|
|
else
|
|
{
|
|
log_info("Reading tesseroids from file %s", args.inputfname);
|
|
modelfile = fopen(args.inputfname, "r");
|
|
if(modelfile == NULL)
|
|
{
|
|
log_error("failed to open file %s", args.inputfname);
|
|
log_warning("Terminating due to bad input");
|
|
log_warning("Try '%s -h' for instructions", progname);
|
|
if(args.logtofile)
|
|
fclose(logfile);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* Read the tesseroids, convert and print to stdout */
|
|
for(line = 1; !feof(modelfile); line++)
|
|
{
|
|
if(fgets(buff, 10000, modelfile) == NULL)
|
|
{
|
|
if(ferror(stdin))
|
|
{
|
|
log_error("problem encountered reading line %d", line);
|
|
error_exit = 1;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Check for comments and blank lines */
|
|
if(buff[0] == '#' || buff[0] == '\r' || buff[0] == '\n')
|
|
{
|
|
continue;
|
|
}
|
|
/* Remove any trailing spaces or newlines */
|
|
strstrip(buff);
|
|
if(gets_tess(buff, &tess))
|
|
{
|
|
log_warning("bad/invalid tesseroid at line %d", line);
|
|
bad_input++;
|
|
continue;
|
|
}
|
|
if(args.use_range)
|
|
{
|
|
mass += tess_range_mass(&tess, 1, args.low_dens,
|
|
args.high_dens);
|
|
size++;
|
|
}
|
|
else
|
|
{
|
|
mass += tess_total_mass(&tess, 1);
|
|
size++;
|
|
}
|
|
}
|
|
}
|
|
if(args.use_range)
|
|
{
|
|
log_info("Mass within density range %g/%g:", args.low_dens,
|
|
args.high_dens);
|
|
}
|
|
else
|
|
{
|
|
log_info("Total mass:");
|
|
}
|
|
|
|
printf("%.15g\n", mass);
|
|
|
|
if(bad_input)
|
|
{
|
|
log_warning("Encountered %d bad input line(s) which were skipped",
|
|
bad_input);
|
|
}
|
|
if(error_exit)
|
|
{
|
|
log_warning("Terminating due to error in input");
|
|
log_warning("Try '%s -h' for instructions", progname);
|
|
}
|
|
else
|
|
{
|
|
log_info("Mass calculated from %d tesseroids", size);
|
|
}
|
|
|
|
/* Clean up */
|
|
if(rc != 3)
|
|
fclose(modelfile);
|
|
if(args.logtofile)
|
|
fclose(logfile);
|
|
return 0;
|
|
}
|