-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgnssIR_api.v0
executable file
·384 lines (367 loc) · 13.4 KB
/
gnssIR_api.v0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
#!/bin/bash
#
echo this was the first version of the gnssIR_api script. It will not work anymore.
echo exiting
exit
if [ "$#" -eq 0 ]; then
echo "----------------GREETINGS FROM KRISTINE'S REFLECTIONS API---------------------"
echo This script runs the archive section of the https://gnss-reflections.org API.
echo There are three required inputs: station, year, and day of year
echo If you have your path defined for where you install the script, type something
echo like this, where p038 is the station name:
echo
echo ./gnssIR_api p038 2019 152
echo
echo but if you want to run it in the same folder you are working in:
echo
echo ./gnssIR_api p038 2019 152
echo
echo The rest of the inputs are optional, as in:
echo
echo -rinex is for RINEX file uploads
echo
echo -e1 and -e2 for elevation angles in degrees \(defaults are 5 and 25\)
echo
echo -azim1 and -azim2 are azimuth angles in degrees \(defaults are 0 and 360\)
echo
echo -freq can be L1, L2, L2C, L5, L1L2CL5, or L1L2. Default is L1
echo
echo -amp is the minimum required amplitude
echo
echo -pk2noise is a qualitry control metric calculated by the peak in the periodogram divided by the average periodogram value over the RH range
echo
echo -h1 and -h2 are reflector height constraints in meters. Defaults are 0.5 and 7 meters
echo
echo If you would like to run multiple days, use the optional -doy_end flag \(LOOKS LIKE THIS HAS NOT BEEN IMPLEMENTED \)
echo
echo Quality Control Parameters:
echo
echo -amp sets the periodogram peak required. The default is 8 - but it is not the right value for all receivers.
echo -pk2noise is peak size related to background noise ratio. Four is the default and good for most snow work
echo
echo The RINEX file must live in the low-rate section of the UNAVCO, SOPAC, CDDIS,
echo or SONEL archives.
echo
echo My API creates a task queue on the site that hosts my API \(heroku\). This usually takes from 5 to 10 seconds to
echo complete. This bash script queries the API every two seconds to see if it has completed.
echo It saves the results \(and tells you where those are being saved\). If you would prefer a different
echo location for your results, change the outputdir variable. The daily set of reflector height
echo outputs includes everything that meets certain quality control metrics.
echo
echo If you input azimuth constraints, the API will output a daily average within those
echo azimuths with additional QC. This is meant to make it easy for the snow/ice communities.
echo This option is NOT appropriate for tides, though it would be appropriate for lake monitoring.
echo
echo This script does not check for all possible errors by users. Further, it is not the right place
echo to look for documentation on the API or for questions about what a reflector height is. For that
echo you need to look at the FAQ/overview section at https://gnss-reflections.org
echo I am working on adding access to the RINEX uploader in this script, but it is not ready
echo for distribution as yet.
echo
echo Update: May 7, 2020
echo I have added limited RINEX upload cability. Use -rinex and the filename. Everything else must
echo obey the original rules AND you can only use the frequencies allowed on the RINEX upload web app, i.e. L1, L2, or L5
echo If I get a chance I will add a L1L2 option. I also still need to provide azimuth constraints.
echo
echo Update: August 26, 2022
echo I have added L1L2, L1L2CL5 to frequency options
echo the API at \https://gnss-reflections.org itself now allows up to 25 observable types in the RINEX 2.11 files.
echo It is GPS only and only allows RH values up to 25 meters.
echo You are further cautioned that using GPS files with 30 second sampling intervals
echo can be dangerous for RH \> 10 meters.
echo
echo It looks like the doy_end option has not been implemented.
echo
echo
echo Happy Reflections,
echo Kristine M. Larson
echo https://kristinelarson.net
echo 2022 August 26
echo
echo Examples:
echo
echo Niwot Ridge, Colorado - L2C is in the RINEX files. Great snow site.
echo ./gnssIR_api nwot 2019 300 -freq L1L2 -h1 0.5 -h2 8 -azim1 45 -azim2 240 -e1 5 -e2 20
echo
echo Phoenix, Ross Ice Shelf, Antarctica - L2C is in the RINEX files
echo ./gnssIR_api phnx 2019 300 -freq L1L2 -h1 0.5 -h2 8
echo
echo Lake Superior, Canada - L1 only as this site does not support modern GPS signal tracking
echo restrictions are to emphasize water reflections
echo ./gnssIR_api mchn 2019 205 -azim1 50 -azim2 210 -h1 2.5 -h2 8 -pk2noise 3.5
echo
echo Island Park, Idaho - would be better if you had access to L2C. Ask UNAVCO about it.
echo ./gnssIR_api p360 2019 100 -pk2noise 3.5
echo
echo
exit
fi
#
# define a new output directory if you like. This one assumes you will put the results in
# the directory below where you are running this code.
outputdir='./solutions'
#
# defaults for elevation angles (degrees), Reflector Heights (meters) and frequency
# h1 should never be less than 0.5
e1=5
e2=25
h1=0.5
h2=7
freq=L1
# these are defaults
pk2noise=4.0
amp=5
rinex=None
# declare these variables so they are integers
declare -i azim1=0
declare -i azim2=360
declare -i doy_end=0
declare -i doy=0
# This variable just sends output to the screen. Even if you don't set it there will be a daily
# average file created
snow=False
#
# I am new to bash scripts - so ....
# As long as there is at least one more argument, keep looping
declare -i k=0
while [[ $# -gt 0 ]]; do
key="$1"
k+=1
#echo key is $k $key
if [ "$k" -eq 1 ]; then
station=$key
shift
elif [ "$k" -eq 2 ]; then
year=$key
shift
elif [ "$k" -eq 3 ]; then
doy=$key
shift
else
case "$key" in
# This is a flag type option. Will catch either -f or --foo
-f|--foo)
FOO=1
;;
# This is an arg value type option. Will catch -o value or --output-file value
-o|--output-file)
shift # past the key and to the value
OUTPUTFILE="$1"
;;
-e1|--min-elev-file)
shift # past the key and to the value
e1="$1"
;;
-e2|--max-elev-file)
shift # past the key and to the value
e2="$1"
;;
-h1|--min-refl-ht)
shift # past the key and to the value
h1="$1"
;;
-h2|--max-refl-ht)
shift # past the key and to the value
h2="$1"
;;
-freq|--frequency)
shift # past the key and to the value
freq="$1"
;;
-amp|--amplitude)
shift # past the key and to the value
amp="$1"
;;
-azim1|--min-azimuth)
shift # past the key and to the value
azim1="$1"
;;
-azim2|--max-azimuth)
shift # past the key and to the value
azim2="$1"
;;
-doy_end|--doy_end)
shift # past the key and to the value
doy_end="$1"
;;
-rinex |--rinex)
shift # past the key and to the value
rinex="$1"
;;
-pk2noise |--pk2noise)
shift # past the key and to the value
pk2noise="$1"
;;
-snow|--snow)
shift # past the key and to the value
snow="$1"
;;
*)
# Do whatever you want with extra options
echo "Unknown option '$key'"
;;
esac
# Shift after checking all the cases to get the next option
shift
fi
done
echo rinex is $rinex
ok=0
if [ "$freq" == "L1" ] || [ "$freq" == "L2" ] ; then
ok=1
echo You have chosen a legal frequency, $freq
elif [ "$freq" == "L5" ] ; then
ok=1
echo You have chosen a legal frequency, $freq
elif [ "$freq" == "L1L2" ] || [ "$freq" == "L2C" ] || [ "$freq" == "L1L2CL5" ]; then
ok=1
echo You have chosen a legal frequency, $freq
fi
if [ $ok -eq 0 ]; then
echo $freq illegal frequency input, exiting
exit
fi
# check doy
if [ $doy -gt 0 ] && [ $doy -lt 367 ]; then
echo This is a legal day of year
else
echo This is an illegal day of year.
exit
fi
# check year
if [ $year -ge 2000 ] && [ $year -lt 2025 ]; then
echo This is a legal year although the year you chose might be in the future
else
echo This is an illegal year.
exit
fi
# check h2
if [ $h2 -gt 25 ] ; then
echo The max reflector height you have chosen is too big for the API.
echo It must be less than 25 meters. For a typical unobstructed site the
echo reflector height minimum should be 0.5 meters. For other sites you
echo might restrict the choices to eliminate soil, e.g. you want to only
echo see water reflections.
exit
fi
# make sure the output directories are there
if [ ! -e "${outputdir}" ]; then
echo "making output directory "
mkdir "${outputdir}"
fi
# make sure the output directories are there
if [ ! -e "${outputdir}/${station}" ]; then
echo "making station output directory "
mkdir "${outputdir}/$station"
fi
if [ ! -e "${outputdir}/${station}/${year}" ]; then
echo "making station year output directory "
mkdir "${outputdir}/${station}/${year}"
fi
# if not set, have doy_end be the same of doy,
if [ $doy_end -eq 0 ]; then
doy_end=$doy
fi
# output for daily averages
comboFile=${outputdir}/${station}_RH_all.csv
echo Combination File $comboFile
echo Day of Year End is $doy_end
echo Look for solutions in the $outputdir directory
# name for the script that calls the API
scriptname=xit.${year}.${station}
# name for the temporary output
dailyname=test.${year}.${station}
while [ $doy -le $doy_end ] ; do
echo CHOICES THAT WILL BE SENT TO THE GNSS-IR API
echo Station $station
echo Year $year
echo Day of Year $doy
echo Elevation Angle choices $e1 $e2
echo Azimuth Angle choices $azim1 $azim2
echo Reflector Height restrictions $h1 $h2
echo Frequency choice $freq
echo Amplitude $amp
echo Peak to Noise $pk2noise
echo End day of year $doy_end
# calculate string doy with exactly three characters
cdoy=$( printf '%03d' $doy )
# make a script to run the webapp
rm -f ${scriptname}
if [ $rinex = None ]; then
echo Archive section
else
echo Uploading RINEX
rm -f out.txt xit
curl -F "file=@${rinex}" -F "azim1=${azim1}" -F "azim2=${azim2}" -F "freq=${freq}" -F "h1=${h1}" -F "h2=${h2}" -F "e1=${e1}" -F "e2=${e2}" -F "pk2noise=${pk2noise}" -F "amp=${amp}" "http://trywithgps2.herokuapp.com/api" > out.txt
var=`grep Numerical out.txt | wc -l`
echo $var
if [ $var -lt 1 ]; then
echo Nothing came back from the app. This usually means you have uploaded an illegal RINEX file
echo or used an illegal RINEX filename. Right now I do not return detailed information if you are
echo accessing the API via this bash script. Rules on RINEX files and their naming conventions
echo The allowed frequencies are slightly different from the archive section, so check that as well.
echo Exiting
exit
fi
echo \# > xit
cat out.txt | grep Numerical | awk '{print "curl https://gnss-reflections.org/"substr($2,7,26) }' >> xit
cat xit
chmod +x xit
./xit > ${dailyname}
# print to screen
cat ${dailyname}
echo Now moving daily results to ${station}_${year}_${cdoy}.txt in the output directory
mv -f ${dailyname} ${outputdir}/${station}/${year}/${station}_${year}_${cdoy}.txt
rm -f ${comboFile}
echo \# https://gnss-reflections.org > ${comboFile}
echo \# Year,DayOfYear,ReflectorHeight\(m\),Month,Day,RHsigma >> ${comboFile}
cat ${outputdir}/${station}/????/*.txt | grep DailyAverage | awk '{print $3"," $4"," $5"," $6"," $7",0"}' >> ${comboFile}
exit
fi
echo \# > ${scriptname}
curl "http://gnss-reflections.org/api?station=${station}&year=${year}&doy=${doy}&freq=${freq}&=${amp}&h1=${h1}&h2=${h2}&e1=${e1}&e2=${e2}&pk2noise=${pk2noise}&azim1=${azim1}&azim2=${azim2}" \
| grep results2 | awk '{print "curl http://gnss-reflections.org/"substr($6,2,45)}' >> ${scriptname}
# make the script executable
chmod +x ${scriptname}
finished=false
# check heroku for the results for 36 seconds and then give up
x=36
while [ "$finished" = false ]
do
echo checking job status every two seconds.
sleep 2
x=$(( $x - 2 ))
if [ $x -eq 0 ]; then
finished=true
echo time has run out, exiting
fi
rm -f ${dailyname}
./${scriptname} > ${dailyname}
var=`grep "still running" ${dailyname} | wc -l`
if [ $var -eq 0 ]; then
finished=true
echo the job has finished
var2=`grep "No Results" ${dailyname} | wc -l`
if [ $var2 -eq 1 ]; then
echo ""
echo Not saving the result file
echo This could mean the RINEX file for station ${station} does not exist at any of the archives.
else
# print results to the screen for the given day
cat ${dailyname}
echo moving daily results to ${station}_${year}_${cdoy}.txt in the output directory
mv -f ${dailyname} ${outputdir}/${station}/${year}/${station}_${year}_${cdoy}.txt
rm -f ${comboFile}
echo \# https://gnss-reflections.org > ${comboFile}
echo \# Year,DayOfYear,ReflectorHeight\(m\),Month,Day,RHsigma >> ${comboFile}
cat ${outputdir}/${station}/????/*.txt | grep DailyAverage | awk '{print $3"," $4"," $5"," $6"," $7",0"}' >> ${comboFile}
fi
fi
done
doy+=1
# end of doy while loop
done
echo Daily averages are stored here: ${comboFile}
echo Output directory ${outputdir}
# clean up
rm -f ${scriptname}