-
Notifications
You must be signed in to change notification settings - Fork 0
/
conversion.go
132 lines (115 loc) · 3.17 KB
/
conversion.go
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
// Package conversion implements conversion of a Observation into
// a string of three lines.
// Text is formatted according to WRF ob.ascii text format,
// which is described by this FORTRAN specification:
//
// INFO = PLATFORM, DATE, NAME, LEVELS, LATITUDE, LONGITUDE, ELEVATION, ID.
// SRFC = SLP, PW (DATA,qc,ERROR).
// EACH = PRES, SPEED, DIR, HEIGHT, TEMP, DEW PT, HUMID (DATA,qc,ERROR)*LEVELS.
// INFO_FMT = (A12,1X,A19,1X,A40,1X,I6,3(F12.3,11X),6X,A40)
// SRFC_FMT = (F12.3,I4,F7.2,F12.3,I4,F7.3)
// EACH_FMT = (3(F12.3,I4,F7.2),11X,3(F12.3,I4,F7.2),11X,3(F12.3,I4,F7.2))
package magda_drones2wrf
import (
"fmt"
"strconv"
"strings"
"time"
)
// qc is
const qc = 0
func str(s string, ln int) string {
strFmt := fmt.Sprintf("%%-%ds", ln)
res := fmt.Sprintf(strFmt, s)
if len(res) <= 40 {
return res
}
return res[0:40]
}
func integer(i int, len int) string {
intS := fmt.Sprintf("%d", i)
strFmt := fmt.Sprintf("%%%ds", len)
return fmt.Sprintf(strFmt, intS)
}
func num(f Value, len float64) string {
if f.IsNaN() {
f = -888888.0
}
strFmt := fmt.Sprintf("%% %sf", strconv.FormatFloat(float64(len), 'f', -1, 64))
return fmt.Sprintf(strFmt, f)
}
func space(n int) string {
return strings.Repeat(" ", n)
}
func date(dt time.Time) string {
return dt.Format("2006-01-02_15:04:05")
}
func dataQCError(data string, err float64) string {
qc := qc
if strings.Contains(data, "-888") {
qc = -88
}
return data +
integer(qc, 4) +
num(Value(err), 7.2)
}
func dataQCError3(data string, err float64) string {
qc := qc
if strings.Contains(data, "-888") {
qc = -88
}
return data +
integer(qc, 4) +
num(Value(err), 7.3)
}
func onlyletters(s string) string {
/*res := ""
for _, rune := range s {
if unicode.IsLetter(rune) && rune < unicode.MaxASCII {
res += string(rune)
} else {
res += string(' ')
}
}
*/
return s
}
// ToWRFASCII converts a Observation into a string
func ToWRFASCII(obs Observation) string {
firstLine :=
str("FM-35 TEMP", 12) +
" " +
date(obs.ObsTimeUtc) +
" " +
str(onlyletters(obs.StationName), 40) +
" " +
integer(obs.NLEV, 6) +
num(Value(obs.Lat), 12.3) +
space(11) +
num(Value(obs.Lon), 12.3) +
space(11) +
num(Value(obs.Elevation), 12.3) +
space(11) +
space(6) +
str(onlyletters(obs.StationID), 40)
surfaceLevelPressure := NaN()
precipTotal := NaN()
secondLine :=
dataQCError(num(surfaceLevelPressure, 12.3), 99.99) +
dataQCError3(num(precipTotal, 12.3), 99.99)
var thirstLines []string
for _, m := range obs.Measures {
thirstLine :=
dataQCError(num((m.Pressure *100), 12.3), ConfigValues.PressureError) +
dataQCError(num(m.WindSpeed, 12.3), ConfigValues.WindSpeedError) +
dataQCError(num(m.WindDirection, 12.3), ConfigValues.WindDirectionError) +
space(11) +
dataQCError(num(m.Altitude, 12.3), ConfigValues.AltitudeError) +
dataQCError(num(m.Temperature, 12.3), ConfigValues.TemperatureError) +
dataQCError(num(m.Dewpoint, 12.3), ConfigValues.DewpointError) +
space(11) +
dataQCError(num(m.Humidity, 12.3), ConfigValues.HumidityError)
thirstLines = append(thirstLines, thirstLine)
}
return firstLine + "\n" + secondLine + "\n" + strings.Join(thirstLines, "\n")
}