Updated with options and some other things to get a usable binary
[baltrad-wrwp.git] / bin / wrwp_main.c
1 /* --------------------------------------------------------------------
2 Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI
3
4 This is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This software is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with HLHDF.  If not, see <http://www.gnu.org/licenses/>.
16 ------------------------------------------------------------------------*/
17 #include "wrwp.h"
18 #include "rave_debug.h"
19 #include <getopt.h>
20 #include <libgen.h>
21
22 static void PrintUsage(char* name, int full)
23 {
24   char* namecopy = RAVE_STRDUP(name);
25
26   printf("Usage: %s [options] <input volume.h5> <output verticalprofile.h5>\n", basename(namecopy));
27
28   if (full) {
29     printf("--help             - Prints this output\n");
30     printf("--verbose          - Produces some information about the generated product\n");
31     printf("--debug            - Produces some debug information during the generation\n");
32     printf("--dz=<value>       - Height interval for deriving a profile [m] (default: %d)\n", DZ);
33     printf("--nodata=<value>   - Nodata value (default: %d)\n", NODATA_VP);
34     printf("--undetect=<value> - Undetect value (default: %d)\n", UNDETECT_VP);
35     printf("--gain=<value>     - Gain value (default: %f)\n", GAIN_VP);
36     printf("--offset=<value>   - Offset value (default: %f)\n", OFFSET_VP);
37     printf("--hmax=<value>     - Maximum height of the profile [m] (default: %d)\n", HMAX);
38     printf("--dmin=<value>     - Minimum distance for deriving a profile [m] (default: %d)\n", DMIN);
39     printf("--dmax=<value>     - Maximum distance for deriving a profile [m] (default: %d)\n", DMAX);
40     printf("--emin=<value>     - Minimum elevation angle [deg] (default: %f)\n", EMIN);
41     printf("--vmin=<value>     - Radial velocity threshold [m/s] (default: %f)\n", VMIN);
42     printf("\n");
43     printf("<input volume.h>  must be a polar volume in ODIM H5 format\n");
44     printf("<output verticalprofile.h5> will be a vertical profile in ODIM H5 format");
45   }
46
47   RAVE_FREE(namecopy);
48 }
49
50 /**
51  * Tries to translate an string into an int value.
52  * @param[in] arg - the argument
53  * @param[in,out] pInt - the outvalue
54  * @return 1 on success otherwise 0
55  */
56 int ParseInt(char* arg, int* pInt)
57 {
58   if (arg != NULL) {
59     int i = 0;
60     while (arg[i] != '\0') {
61       if (arg[i] < '0' || arg[i] > '9') {
62         return 0;
63       }
64       i++;
65     }
66   }
67   if (arg != NULL && pInt != NULL && sscanf(arg, "%d",pInt) == 1) {
68     return 1;
69   }
70   return 0;
71 }
72
73 /**
74  * Tries to translate an string into an int value.
75  * @param[in] arg - the argument
76  * @param[in,out] pDouble - the outvalue
77  * @return 1 on success otherwise 0
78  */
79 int ParseDouble(char* arg, double* pDouble)
80 {
81   if (arg != NULL) {
82     int i = 0;
83     int nrDots = 0;
84     while (arg[i] != '\0') {
85       if (arg[i] < '0' || arg[i] > '9') {
86         if (arg[i] == '.' && nrDots==0) {
87           nrDots++;
88         } else {
89           return 0;
90         }
91       }
92       i++;
93     }
94   }
95   if (arg != NULL && pDouble != NULL && sscanf(arg, "%lf",pDouble) == 1) {
96     return 1;
97   }
98   return 0;
99 }
100
101 /** Main function for deriving weather radar wind and reflectivity profiles
102  * @file
103  * @author G´┐Żnther Haase, SMHI
104  * @date 2011-11-29
105  */
106 int main (int argc,char *argv[]) {
107         RaveIO_t* raveio = NULL;
108         PolarVolume_t* inobj = NULL;
109         VerticalProfile_t* result = NULL;
110         Wrwp_t* wrwp = NULL;
111         int exitcode = 127;
112         char* inputfile = NULL; /* do not delete */
113         char* outputfile = NULL; /* do not delete */
114
115         int verbose_flag=0;
116         int debug_flag=0;
117         int help_flag=0;
118         int dz_value = DZ;
119         int nodata_vp = NODATA_VP;
120         int undetect_vp = UNDETECT_VP;
121         double gain_vp = GAIN_VP;
122         double offset_vp = OFFSET_VP;
123         int hmax = HMAX;
124         int dmin = DMIN;
125         int dmax = DMAX;
126         double emin = EMIN;
127         double vmin = VMIN;
128
129         int getopt_ret, option_index;
130
131         struct option long_options[] = {
132             {"help", no_argument, &help_flag, 1},
133             {"verbose", no_argument, &verbose_flag, 1},
134       {"debug", no_argument, &debug_flag, 1},
135             {"dz", optional_argument, 0, 'z'},
136             {"nodata", optional_argument, 0, 'n'},
137             {"undetect", optional_argument, 0, 'u'},
138       {"gain", optional_argument, 0, 'g'},
139       {"offset", optional_argument, 0, 'o'},
140       {"hmax", optional_argument, 0, 'h'},
141       {"dmin", optional_argument, 0, 'd'},
142       {"dmax", optional_argument, 0, 'D'},
143       {"emin", optional_argument, 0, 'e'},
144       {"vmin", optional_argument, 0, 'v'},
145             {0, 0, 0, 0}
146         };
147
148
149         Rave_initializeDebugger();
150         Rave_setDebugLevel(RAVE_INFO);
151
152   while (1) {
153       getopt_ret = getopt_long( argc, argv, "",
154                                 long_options,  &option_index);
155       if (getopt_ret == -1) break;
156       if (help_flag) {
157         PrintUsage(argv[0], 1);
158         exitcode=1;
159         goto done;
160       }
161       if (verbose_flag) {
162         Rave_setDebugLevel(RAVE_DEBUG);
163       }
164
165       switch(getopt_ret) {
166       case 0:
167         /* Here all non named options will arrive */
168         /*printf("option %s\n", long_options[option_index].name);*/
169         break;
170       case 'z':
171         if (!ParseInt(optarg, &dz_value)) {
172           fprintf(stderr, "--dz=<value> must be an integer value\n");
173           PrintUsage(argv[0], 0);
174           goto done;
175         }
176         break;
177       case 'n':
178         if (!ParseInt(optarg, &nodata_vp)) {
179           fprintf(stderr, "--nodata=<value> must be an integer value\n");
180           PrintUsage(argv[0], 0);
181           goto done;
182         }
183         break;
184       case 'u':
185         if (!ParseInt(optarg, &undetect_vp)) {
186           fprintf(stderr, "--undetect=<value> must be an integer value\n");
187           PrintUsage(argv[0], 0);
188           goto done;
189         }
190         break;
191       case 'g':
192         if (!ParseDouble(optarg, &gain_vp)) {
193           fprintf(stderr, "--gain=<value> must be a double value\n");
194           PrintUsage(argv[0], 0);
195           goto done;
196         }
197         break;
198       case 'o':
199         if (!ParseDouble(optarg, &offset_vp)) {
200           fprintf(stderr, "--offset=<value> must be a double value\n");
201           PrintUsage(argv[0], 0);
202           goto done;
203         }
204         break;
205       case 'h':
206         if (!ParseInt(optarg, &hmax)) {
207           fprintf(stderr, "--hmax=<value> must be an integer value\n");
208           PrintUsage(argv[0], 0);
209           goto done;
210         }
211         break;
212       case 'd':
213         if (!ParseInt(optarg, &dmin)) {
214           fprintf(stderr, "--dmin=<value> must be an integer value\n");
215           PrintUsage(argv[0], 0);
216           goto done;
217         }
218         break;
219       case 'D':
220         if (!ParseInt(optarg, &dmax)) {
221           fprintf(stderr, "--dmax=<value> must be an integer value\n");
222           PrintUsage(argv[0], 0);
223           goto done;
224         }
225         break;
226       case 'e':
227         if (!ParseDouble(optarg, &emin)) {
228           fprintf(stderr, "--emin=<value> must be a double value\n");
229           PrintUsage(argv[0], 0);
230           goto done;
231         }
232         break;
233       case 'v':
234         if (!ParseDouble(optarg, &vmin)) {
235           fprintf(stderr, "--vmin=<value> must be a double value\n");
236           PrintUsage(argv[0], 0);
237           goto done;
238         }
239         break;
240       case '?':
241       default:
242         fprintf(stderr, "Unknown argument\n");
243         PrintUsage(argv[0], 0);
244         break;
245       }
246   }
247
248   if (argc - optind != 2) {
249     PrintUsage(argv[0], 0);
250     goto done;
251   }
252
253   inputfile=argv[optind++];
254   outputfile=argv[optind++];
255
256   if (argc<3) {
257                 printf ("Usage: %s <input ODIM_H5 polar volume> <output ODIM_H5 polar volume> \n",argv[0]);
258                 exit (1);
259         }
260
261         raveio = RaveIO_open(inputfile);
262         if (raveio == NULL) {
263           fprintf(stderr, "Failed to open file = %s\n", inputfile);
264           goto done;
265         }
266
267         wrwp = RAVE_OBJECT_NEW(&Wrwp_TYPE);
268         if (wrwp == NULL) {
269           fprintf(stderr, "Failed to create wrwp object\n");
270           goto done;
271         }
272
273         Wrwp_setDZ(wrwp, dz_value);
274         Wrwp_setNODATA_VP(wrwp, nodata_vp);
275         Wrwp_setUNDETECT_VP(wrwp, undetect_vp);
276         Wrwp_setOFFSET_VP(wrwp, offset_vp);
277         Wrwp_setGAIN_VP(wrwp, gain_vp);
278         Wrwp_setHMAX(wrwp, hmax);
279         Wrwp_setDMIN(wrwp, dmin);
280         Wrwp_setDMAX(wrwp, dmax);
281         Wrwp_setEMIN(wrwp, emin);
282         Wrwp_setVMIN(wrwp, vmin);
283
284         /*Opening of HDF5 radar input file.*/
285         if (RaveIO_getObjectType(raveio)== Rave_ObjectType_PVOL) {
286                 inobj = (PolarVolume_t*)RaveIO_getObject(raveio);
287         }
288         else {
289                 printf ("Input file is not a polar volume. Giving up ...\n");
290                 goto done;
291         }
292         RaveIO_close (raveio);
293
294         result = Wrwp_generate(wrwp, inobj, NULL);
295         if (inobj == NULL) {
296                 printf ("Could not derive wind profile %s, exiting ...\n", argv[1]);
297                 goto done;
298         }
299
300         RaveIO_setObject(raveio, (RaveCoreObject*)result);
301
302         if (!RaveIO_save(raveio, outputfile))
303           goto done;
304
305   if (debug_flag) {
306     printf("Generated vertical profile...\n");
307     printf("Input file: %s\n", inputfile);
308     printf("Output file: %s\n", outputfile);
309     printf("DZ         = %d\n", Wrwp_getDZ(wrwp));
310     printf("NODATA     = %d\n", Wrwp_getNODATA_VP(wrwp));
311     printf("UNDETECT   = %d\n", Wrwp_getUNDETECT_VP(wrwp));
312     printf("GAIN       = %lf\n", Wrwp_getGAIN_VP(wrwp));
313     printf("OFFSET     = %lf\n", Wrwp_getOFFSET_VP(wrwp));
314     printf("HMAX       = %d\n", Wrwp_getHMAX(wrwp));
315     printf("DMIN       = %d\n", Wrwp_getDMIN(wrwp));
316     printf("DMAX       = %d\n", Wrwp_getDMAX(wrwp));
317     printf("EMIN       = %lf\n", Wrwp_getEMIN(wrwp));
318     printf("VMIN       = %lf\n", Wrwp_getVMIN(wrwp));
319   }
320
321         exitcode = 0;
322 done:
323         RAVE_OBJECT_RELEASE(raveio);
324         RAVE_OBJECT_RELEASE(inobj);
325         RAVE_OBJECT_RELEASE(result);
326
327         return exitcode;
328 }